// <auto-generated>
//     Generated by the protocol buffer compiler.  DO NOT EDIT!
//     source: google/protobuf/descriptor.proto
// </auto-generated>
#pragma warning disable 1591, 0612, 3021, 8981
#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",
            "b3RvYnVmIlUKEUZpbGVEZXNjcmlwdG9yU2V0EjIKBGZpbGUYASADKAsyJC5n",
            "b29nbGUucHJvdG9idWYuRmlsZURlc2NyaXB0b3JQcm90byoMCIDsyv8BEIHs",
            "yv8BIqEEChNGaWxlRGVzY3JpcHRvclByb3RvEgwKBG5hbWUYASABKAkSDwoH",
            "cGFja2FnZRgCIAEoCRISCgpkZXBlbmRlbmN5GAMgAygJEhkKEXB1YmxpY19k",
            "ZXBlbmRlbmN5GAogAygFEhcKD3dlYWtfZGVwZW5kZW5jeRgLIAMoBRIZChFv",
            "cHRpb25fZGVwZW5kZW5jeRgPIAMoCRI2CgxtZXNzYWdlX3R5cGUYBCADKAsy",
            "IC5nb29nbGUucHJvdG9idWYuRGVzY3JpcHRvclByb3RvEjcKCWVudW1fdHlw",
            "ZRgFIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5FbnVtRGVzY3JpcHRvclByb3Rv",
            "EjgKB3NlcnZpY2UYBiADKAsyJy5nb29nbGUucHJvdG9idWYuU2VydmljZURl",
            "c2NyaXB0b3JQcm90bxI4CglleHRlbnNpb24YByADKAsyJS5nb29nbGUucHJv",
            "dG9idWYuRmllbGREZXNjcmlwdG9yUHJvdG8SLQoHb3B0aW9ucxgIIAEoCzIc",
            "Lmdvb2dsZS5wcm90b2J1Zi5GaWxlT3B0aW9ucxI5ChBzb3VyY2VfY29kZV9p",
            "bmZvGAkgASgLMh8uZ29vZ2xlLnByb3RvYnVmLlNvdXJjZUNvZGVJbmZvEg4K",
            "BnN5bnRheBgMIAEoCRIpCgdlZGl0aW9uGA4gASgOMhguZ29vZ2xlLnByb3Rv",
            "YnVmLkVkaXRpb24i4AUKD0Rlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJ",
            "EjQKBWZpZWxkGAIgAygLMiUuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3Jp",
            "cHRvclByb3RvEjgKCWV4dGVuc2lvbhgGIAMoCzIlLmdvb2dsZS5wcm90b2J1",
            "Zi5GaWVsZERlc2NyaXB0b3JQcm90bxI1CgtuZXN0ZWRfdHlwZRgDIAMoCzIg",
            "Lmdvb2dsZS5wcm90b2J1Zi5EZXNjcmlwdG9yUHJvdG8SNwoJZW51bV90eXBl",
            "GAQgAygLMiQuZ29vZ2xlLnByb3RvYnVmLkVudW1EZXNjcmlwdG9yUHJvdG8S",
            "SAoPZXh0ZW5zaW9uX3JhbmdlGAUgAygLMi8uZ29vZ2xlLnByb3RvYnVmLkRl",
            "c2NyaXB0b3JQcm90by5FeHRlbnNpb25SYW5nZRI5CgpvbmVvZl9kZWNsGAgg",
            "AygLMiUuZ29vZ2xlLnByb3RvYnVmLk9uZW9mRGVzY3JpcHRvclByb3RvEjAK",
            "B29wdGlvbnMYByABKAsyHy5nb29nbGUucHJvdG9idWYuTWVzc2FnZU9wdGlv",
            "bnMSRgoOcmVzZXJ2ZWRfcmFuZ2UYCSADKAsyLi5nb29nbGUucHJvdG9idWYu",
            "RGVzY3JpcHRvclByb3RvLlJlc2VydmVkUmFuZ2USFQoNcmVzZXJ2ZWRfbmFt",
            "ZRgKIAMoCRI1Cgp2aXNpYmlsaXR5GAsgASgOMiEuZ29vZ2xlLnByb3RvYnVm",
            "LlN5bWJvbFZpc2liaWxpdHkaZQoORXh0ZW5zaW9uUmFuZ2USDQoFc3RhcnQY",
            "ASABKAUSCwoDZW5kGAIgASgFEjcKB29wdGlvbnMYAyABKAsyJi5nb29nbGUu",
            "cHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zGisKDVJlc2VydmVkUmFu",
            "Z2USDQoFc3RhcnQYASABKAUSCwoDZW5kGAIgASgFIuUDChVFeHRlbnNpb25S",
            "YW5nZU9wdGlvbnMSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQu",
            "Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24STAoLZGVjbGFy",
            "YXRpb24YAiADKAsyMi5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VP",
            "cHRpb25zLkRlY2xhcmF0aW9uQgOIAQISLQoIZmVhdHVyZXMYMiABKAsyGy5n",
            "b29nbGUucHJvdG9idWYuRmVhdHVyZVNldBJfCgx2ZXJpZmljYXRpb24YAyAB",
            "KA4yOC5nb29nbGUucHJvdG9idWYuRXh0ZW5zaW9uUmFuZ2VPcHRpb25zLlZl",
            "cmlmaWNhdGlvblN0YXRlOgpVTlZFUklGSUVEQgOIAQIaaAoLRGVjbGFyYXRp",
            "b24SDgoGbnVtYmVyGAEgASgFEhEKCWZ1bGxfbmFtZRgCIAEoCRIMCgR0eXBl",
            "GAMgASgJEhAKCHJlc2VydmVkGAUgASgIEhAKCHJlcGVhdGVkGAYgASgISgQI",
            "BBAFIjQKEVZlcmlmaWNhdGlvblN0YXRlEg8KC0RFQ0xBUkFUSU9OEAASDgoK",
            "VU5WRVJJRklFRBABKgkI6AcQgICAgAIi1QUKFEZpZWxkRGVzY3JpcHRvclBy",
            "b3RvEgwKBG5hbWUYASABKAkSDgoGbnVtYmVyGAMgASgFEjoKBWxhYmVsGAQg",
            "ASgOMisuZ29vZ2xlLnByb3RvYnVmLkZpZWxkRGVzY3JpcHRvclByb3RvLkxh",
            "YmVsEjgKBHR5cGUYBSABKA4yKi5nb29nbGUucHJvdG9idWYuRmllbGREZXNj",
            "cmlwdG9yUHJvdG8uVHlwZRIRCgl0eXBlX25hbWUYBiABKAkSEAoIZXh0ZW5k",
            "ZWUYAiABKAkSFQoNZGVmYXVsdF92YWx1ZRgHIAEoCRITCgtvbmVvZl9pbmRl",
            "eBgJIAEoBRIRCglqc29uX25hbWUYCiABKAkSLgoHb3B0aW9ucxgIIAEoCzId",
            "Lmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMSFwoPcHJvdG8zX29wdGlv",
            "bmFsGBEgASgIIrYCCgRUeXBlEg8KC1RZUEVfRE9VQkxFEAESDgoKVFlQRV9G",
            "TE9BVBACEg4KClRZUEVfSU5UNjQQAxIPCgtUWVBFX1VJTlQ2NBAEEg4KClRZ",
            "UEVfSU5UMzIQBRIQCgxUWVBFX0ZJWEVENjQQBhIQCgxUWVBFX0ZJWEVEMzIQ",
            "BxINCglUWVBFX0JPT0wQCBIPCgtUWVBFX1NUUklORxAJEg4KClRZUEVfR1JP",
            "VVAQChIQCgxUWVBFX01FU1NBR0UQCxIOCgpUWVBFX0JZVEVTEAwSDwoLVFlQ",
            "RV9VSU5UMzIQDRINCglUWVBFX0VOVU0QDhIRCg1UWVBFX1NGSVhFRDMyEA8S",
            "EQoNVFlQRV9TRklYRUQ2NBAQEg8KC1RZUEVfU0lOVDMyEBESDwoLVFlQRV9T",
            "SU5UNjQQEiJDCgVMYWJlbBISCg5MQUJFTF9PUFRJT05BTBABEhIKDkxBQkVM",
            "X1JFUEVBVEVEEAMSEgoOTEFCRUxfUkVRVUlSRUQQAiJUChRPbmVvZkRlc2Ny",
            "aXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEi4KB29wdGlvbnMYAiABKAsyHS5n",
            "b29nbGUucHJvdG9idWYuT25lb2ZPcHRpb25zItsCChNFbnVtRGVzY3JpcHRv",
            "clByb3RvEgwKBG5hbWUYASABKAkSOAoFdmFsdWUYAiADKAsyKS5nb29nbGUu",
            "cHJvdG9idWYuRW51bVZhbHVlRGVzY3JpcHRvclByb3RvEi0KB29wdGlvbnMY",
            "AyABKAsyHC5nb29nbGUucHJvdG9idWYuRW51bU9wdGlvbnMSTgoOcmVzZXJ2",
            "ZWRfcmFuZ2UYBCADKAsyNi5nb29nbGUucHJvdG9idWYuRW51bURlc2NyaXB0",
            "b3JQcm90by5FbnVtUmVzZXJ2ZWRSYW5nZRIVCg1yZXNlcnZlZF9uYW1lGAUg",
            "AygJEjUKCnZpc2liaWxpdHkYBiABKA4yIS5nb29nbGUucHJvdG9idWYuU3lt",
            "Ym9sVmlzaWJpbGl0eRovChFFbnVtUmVzZXJ2ZWRSYW5nZRINCgVzdGFydBgB",
            "IAEoBRILCgNlbmQYAiABKAUibAoYRW51bVZhbHVlRGVzY3JpcHRvclByb3Rv",
            "EgwKBG5hbWUYASABKAkSDgoGbnVtYmVyGAIgASgFEjIKB29wdGlvbnMYAyAB",
            "KAsyIS5nb29nbGUucHJvdG9idWYuRW51bVZhbHVlT3B0aW9ucyKeAQoWU2Vy",
            "dmljZURlc2NyaXB0b3JQcm90bxIMCgRuYW1lGAEgASgJEjYKBm1ldGhvZBgC",
            "IAMoCzImLmdvb2dsZS5wcm90b2J1Zi5NZXRob2REZXNjcmlwdG9yUHJvdG8S",
            "MAoHb3B0aW9ucxgDIAEoCzIfLmdvb2dsZS5wcm90b2J1Zi5TZXJ2aWNlT3B0",
            "aW9uc0oECAQQBVIGc3RyZWFtIsEBChVNZXRob2REZXNjcmlwdG9yUHJvdG8S",
            "DAoEbmFtZRgBIAEoCRISCgppbnB1dF90eXBlGAIgASgJEhMKC291dHB1dF90",
            "eXBlGAMgASgJEi8KB29wdGlvbnMYBCABKAsyHi5nb29nbGUucHJvdG9idWYu",
            "TWV0aG9kT3B0aW9ucxIfChBjbGllbnRfc3RyZWFtaW5nGAUgASgIOgVmYWxz",
            "ZRIfChBzZXJ2ZXJfc3RyZWFtaW5nGAYgASgIOgVmYWxzZSLLBgoLRmlsZU9w",
            "dGlvbnMSFAoMamF2YV9wYWNrYWdlGAEgASgJEhwKFGphdmFfb3V0ZXJfY2xh",
            "c3NuYW1lGAggASgJEiIKE2phdmFfbXVsdGlwbGVfZmlsZXMYCiABKAg6BWZh",
            "bHNlEikKHWphdmFfZ2VuZXJhdGVfZXF1YWxzX2FuZF9oYXNoGBQgASgIQgIY",
            "ARIlChZqYXZhX3N0cmluZ19jaGVja191dGY4GBsgASgIOgVmYWxzZRJGCgxv",
            "cHRpbWl6ZV9mb3IYCSABKA4yKS5nb29nbGUucHJvdG9idWYuRmlsZU9wdGlv",
            "bnMuT3B0aW1pemVNb2RlOgVTUEVFRBISCgpnb19wYWNrYWdlGAsgASgJEiIK",
            "E2NjX2dlbmVyaWNfc2VydmljZXMYECABKAg6BWZhbHNlEiQKFWphdmFfZ2Vu",
            "ZXJpY19zZXJ2aWNlcxgRIAEoCDoFZmFsc2USIgoTcHlfZ2VuZXJpY19zZXJ2",
            "aWNlcxgSIAEoCDoFZmFsc2USGQoKZGVwcmVjYXRlZBgXIAEoCDoFZmFsc2US",
            "HgoQY2NfZW5hYmxlX2FyZW5hcxgfIAEoCDoEdHJ1ZRIZChFvYmpjX2NsYXNz",
            "X3ByZWZpeBgkIAEoCRIYChBjc2hhcnBfbmFtZXNwYWNlGCUgASgJEhQKDHN3",
            "aWZ0X3ByZWZpeBgnIAEoCRIYChBwaHBfY2xhc3NfcHJlZml4GCggASgJEhUK",
            "DXBocF9uYW1lc3BhY2UYKSABKAkSHgoWcGhwX21ldGFkYXRhX25hbWVzcGFj",
            "ZRgsIAEoCRIUCgxydWJ5X3BhY2thZ2UYLSABKAkSLQoIZmVhdHVyZXMYMiAB",
            "KAsyGy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldBJDChR1bmludGVycHJl",
            "dGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYuVW5pbnRlcnBy",
            "ZXRlZE9wdGlvbiI6CgxPcHRpbWl6ZU1vZGUSCQoFU1BFRUQQARINCglDT0RF",
            "X1NJWkUQAhIQCgxMSVRFX1JVTlRJTUUQAyoJCOgHEICAgIACSgQIKhArSgQI",
            "JhAnUhRwaHBfZ2VuZXJpY19zZXJ2aWNlcyLnAgoOTWVzc2FnZU9wdGlvbnMS",
            "JgoXbWVzc2FnZV9zZXRfd2lyZV9mb3JtYXQYASABKAg6BWZhbHNlEi4KH25v",
            "X3N0YW5kYXJkX2Rlc2NyaXB0b3JfYWNjZXNzb3IYAiABKAg6BWZhbHNlEhkK",
            "CmRlcHJlY2F0ZWQYAyABKAg6BWZhbHNlEhEKCW1hcF9lbnRyeRgHIAEoCBIy",
            "CiZkZXByZWNhdGVkX2xlZ2FjeV9qc29uX2ZpZWxkX2NvbmZsaWN0cxgLIAEo",
            "CEICGAESLQoIZmVhdHVyZXMYDCABKAsyGy5nb29nbGUucHJvdG9idWYuRmVh",
            "dHVyZVNldBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29n",
            "bGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACSgQI",
            "BBAFSgQIBRAGSgQIBhAHSgQICBAJSgQICRAKIqcLCgxGaWVsZE9wdGlvbnMS",
            "OgoFY3R5cGUYASABKA4yIy5nb29nbGUucHJvdG9idWYuRmllbGRPcHRpb25z",
            "LkNUeXBlOgZTVFJJTkcSDgoGcGFja2VkGAIgASgIEj8KBmpzdHlwZRgGIAEo",
            "DjIkLmdvb2dsZS5wcm90b2J1Zi5GaWVsZE9wdGlvbnMuSlNUeXBlOglKU19O",
            "T1JNQUwSEwoEbGF6eRgFIAEoCDoFZmFsc2USHgoPdW52ZXJpZmllZF9sYXp5",
            "GA8gASgIOgVmYWxzZRIZCgpkZXByZWNhdGVkGAMgASgIOgVmYWxzZRIXCgR3",
            "ZWFrGAogASgIOgVmYWxzZUICGAESGwoMZGVidWdfcmVkYWN0GBAgASgIOgVm",
            "YWxzZRJACglyZXRlbnRpb24YESABKA4yLS5nb29nbGUucHJvdG9idWYuRmll",
            "bGRPcHRpb25zLk9wdGlvblJldGVudGlvbhI/Cgd0YXJnZXRzGBMgAygOMi4u",
            "Z29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5PcHRpb25UYXJnZXRUeXBl",
            "EkYKEGVkaXRpb25fZGVmYXVsdHMYFCADKAsyLC5nb29nbGUucHJvdG9idWYu",
            "RmllbGRPcHRpb25zLkVkaXRpb25EZWZhdWx0Ei0KCGZlYXR1cmVzGBUgASgL",
            "MhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSRQoPZmVhdHVyZV9zdXBw",
            "b3J0GBYgASgLMiwuZ29vZ2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5GZWF0",
            "dXJlU3VwcG9ydBJDChR1bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5n",
            "b29nbGUucHJvdG9idWYuVW5pbnRlcnByZXRlZE9wdGlvbhpKCg5FZGl0aW9u",
            "RGVmYXVsdBIpCgdlZGl0aW9uGAMgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVk",
            "aXRpb24SDQoFdmFsdWUYAiABKAkazAEKDkZlYXR1cmVTdXBwb3J0EjQKEmVk",
            "aXRpb25faW50cm9kdWNlZBgBIAEoDjIYLmdvb2dsZS5wcm90b2J1Zi5FZGl0",
            "aW9uEjQKEmVkaXRpb25fZGVwcmVjYXRlZBgCIAEoDjIYLmdvb2dsZS5wcm90",
            "b2J1Zi5FZGl0aW9uEhsKE2RlcHJlY2F0aW9uX3dhcm5pbmcYAyABKAkSMQoP",
            "ZWRpdGlvbl9yZW1vdmVkGAQgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRp",
            "b24iLwoFQ1R5cGUSCgoGU1RSSU5HEAASCAoEQ09SRBABEhAKDFNUUklOR19Q",
            "SUVDRRACIjUKBkpTVHlwZRINCglKU19OT1JNQUwQABINCglKU19TVFJJTkcQ",
            "ARINCglKU19OVU1CRVIQAiJVCg9PcHRpb25SZXRlbnRpb24SFQoRUkVURU5U",
            "SU9OX1VOS05PV04QABIVChFSRVRFTlRJT05fUlVOVElNRRABEhQKEFJFVEVO",
            "VElPTl9TT1VSQ0UQAiKMAgoQT3B0aW9uVGFyZ2V0VHlwZRIXChNUQVJHRVRf",
            "VFlQRV9VTktOT1dOEAASFAoQVEFSR0VUX1RZUEVfRklMRRABEh8KG1RBUkdF",
            "VF9UWVBFX0VYVEVOU0lPTl9SQU5HRRACEhcKE1RBUkdFVF9UWVBFX01FU1NB",
            "R0UQAxIVChFUQVJHRVRfVFlQRV9GSUVMRBAEEhUKEVRBUkdFVF9UWVBFX09O",
            "RU9GEAUSFAoQVEFSR0VUX1RZUEVfRU5VTRAGEhoKFlRBUkdFVF9UWVBFX0VO",
            "VU1fRU5UUlkQBxIXChNUQVJHRVRfVFlQRV9TRVJWSUNFEAgSFgoSVEFSR0VU",
            "X1RZUEVfTUVUSE9EEAkqCQjoBxCAgICAAkoECAQQBUoECBIQEyKNAQoMT25l",
            "b2ZPcHRpb25zEi0KCGZlYXR1cmVzGAEgASgLMhsuZ29vZ2xlLnByb3RvYnVm",
            "LkZlYXR1cmVTZXQSQwoUdW5pbnRlcnByZXRlZF9vcHRpb24Y5wcgAygLMiQu",
            "Z29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0ZWRPcHRpb24qCQjoBxCAgICA",
            "AiL2AQoLRW51bU9wdGlvbnMSEwoLYWxsb3dfYWxpYXMYAiABKAgSGQoKZGVw",
            "cmVjYXRlZBgDIAEoCDoFZmFsc2USMgomZGVwcmVjYXRlZF9sZWdhY3lfanNv",
            "bl9maWVsZF9jb25mbGljdHMYBiABKAhCAhgBEi0KCGZlYXR1cmVzGAcgASgL",
            "MhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnByZXRl",
            "ZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJwcmV0",
            "ZWRPcHRpb24qCQjoBxCAgICAAkoECAUQBiKQAgoQRW51bVZhbHVlT3B0aW9u",
            "cxIZCgpkZXByZWNhdGVkGAEgASgIOgVmYWxzZRItCghmZWF0dXJlcxgCIAEo",
            "CzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0EhsKDGRlYnVnX3JlZGFj",
            "dBgDIAEoCDoFZmFsc2USRQoPZmVhdHVyZV9zdXBwb3J0GAQgASgLMiwuZ29v",
            "Z2xlLnByb3RvYnVmLkZpZWxkT3B0aW9ucy5GZWF0dXJlU3VwcG9ydBJDChR1",
            "bmludGVycHJldGVkX29wdGlvbhjnByADKAsyJC5nb29nbGUucHJvdG9idWYu",
            "VW5pbnRlcnByZXRlZE9wdGlvbioJCOgHEICAgIACIqoBCg5TZXJ2aWNlT3B0",
            "aW9ucxItCghmZWF0dXJlcxgiIAEoCzIbLmdvb2dsZS5wcm90b2J1Zi5GZWF0",
            "dXJlU2V0EhkKCmRlcHJlY2F0ZWQYISABKAg6BWZhbHNlEkMKFHVuaW50ZXJw",
            "cmV0ZWRfb3B0aW9uGOcHIAMoCzIkLmdvb2dsZS5wcm90b2J1Zi5VbmludGVy",
            "cHJldGVkT3B0aW9uKgkI6AcQgICAgAIi3AIKDU1ldGhvZE9wdGlvbnMSGQoK",
            "ZGVwcmVjYXRlZBghIAEoCDoFZmFsc2USXwoRaWRlbXBvdGVuY3lfbGV2ZWwY",
            "IiABKA4yLy5nb29nbGUucHJvdG9idWYuTWV0aG9kT3B0aW9ucy5JZGVtcG90",
            "ZW5jeUxldmVsOhNJREVNUE9URU5DWV9VTktOT1dOEi0KCGZlYXR1cmVzGCMg",
            "ASgLMhsuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQSQwoUdW5pbnRlcnBy",
            "ZXRlZF9vcHRpb24Y5wcgAygLMiQuZ29vZ2xlLnByb3RvYnVmLlVuaW50ZXJw",
            "cmV0ZWRPcHRpb24iUAoQSWRlbXBvdGVuY3lMZXZlbBIXChNJREVNUE9URU5D",
            "WV9VTktOT1dOEAASEwoPTk9fU0lERV9FRkZFQ1RTEAESDgoKSURFTVBPVEVO",
            "VBACKgkI6AcQgICAgAIingIKE1VuaW50ZXJwcmV0ZWRPcHRpb24SOwoEbmFt",
            "ZRgCIAMoCzItLmdvb2dsZS5wcm90b2J1Zi5VbmludGVycHJldGVkT3B0aW9u",
            "Lk5hbWVQYXJ0EhgKEGlkZW50aWZpZXJfdmFsdWUYAyABKAkSGgoScG9zaXRp",
            "dmVfaW50X3ZhbHVlGAQgASgEEhoKEm5lZ2F0aXZlX2ludF92YWx1ZRgFIAEo",
            "AxIUCgxkb3VibGVfdmFsdWUYBiABKAESFAoMc3RyaW5nX3ZhbHVlGAcgASgM",
            "EhcKD2FnZ3JlZ2F0ZV92YWx1ZRgIIAEoCRozCghOYW1lUGFydBIRCgluYW1l",
            "X3BhcnQYASACKAkSFAoMaXNfZXh0ZW5zaW9uGAIgAigIIoMOCgpGZWF0dXJl",
            "U2V0EoIBCg5maWVsZF9wcmVzZW5jZRgBIAEoDjIpLmdvb2dsZS5wcm90b2J1",
            "Zi5GZWF0dXJlU2V0LkZpZWxkUHJlc2VuY2VCP4gBAZgBBJgBAaIBDRIIRVhQ",
            "TElDSVQYhAeiAQ0SCElNUExJQ0lUGOcHogENEghFWFBMSUNJVBjoB7IBAwjo",
            "BxJiCgllbnVtX3R5cGUYAiABKA4yJC5nb29nbGUucHJvdG9idWYuRmVhdHVy",
            "ZVNldC5FbnVtVHlwZUIpiAEBmAEGmAEBogELEgZDTE9TRUQYhAeiAQkSBE9Q",
            "RU4Y5weyAQMI6AcSgQEKF3JlcGVhdGVkX2ZpZWxkX2VuY29kaW5nGAMgASgO",
            "MjEuZ29vZ2xlLnByb3RvYnVmLkZlYXR1cmVTZXQuUmVwZWF0ZWRGaWVsZEVu",
            "Y29kaW5nQi2IAQGYAQSYAQGiAQ0SCEVYUEFOREVEGIQHogELEgZQQUNLRUQY",
            "5weyAQMI6AcSbgoPdXRmOF92YWxpZGF0aW9uGAQgASgOMiouZ29vZ2xlLnBy",
            "b3RvYnVmLkZlYXR1cmVTZXQuVXRmOFZhbGlkYXRpb25CKYgBAZgBBJgBAaIB",
            "CRIETk9ORRiEB6IBCxIGVkVSSUZZGOcHsgEDCOgHEm0KEG1lc3NhZ2VfZW5j",
            "b2RpbmcYBSABKA4yKy5nb29nbGUucHJvdG9idWYuRmVhdHVyZVNldC5NZXNz",
            "YWdlRW5jb2RpbmdCJogBAZgBBJgBAaIBFBIPTEVOR1RIX1BSRUZJWEVEGIQH",
            "sgEDCOgHEnYKC2pzb25fZm9ybWF0GAYgASgOMiYuZ29vZ2xlLnByb3RvYnVm",
            "LkZlYXR1cmVTZXQuSnNvbkZvcm1hdEI5iAEBmAEDmAEGmAEBogEXEhJMRUdB",
            "Q1lfQkVTVF9FRkZPUlQYhAeiAQoSBUFMTE9XGOcHsgEDCOgHEpcBChRlbmZv",
            "cmNlX25hbWluZ19zdHlsZRgHIAEoDjIuLmdvb2dsZS5wcm90b2J1Zi5GZWF0",
            "dXJlU2V0LkVuZm9yY2VOYW1pbmdTdHlsZUJJiAECmAEBmAECmAEDmAEEmAEF",
            "mAEGmAEHmAEImAEJogEREgxTVFlMRV9MRUdBQ1kYhAeiAQ4SCVNUWUxFMjAy",
            "NBjpB7IBAwjpBxKgAQoZZGVmYXVsdF9zeW1ib2xfdmlzaWJpbGl0eRgIIAEo",
            "DjJFLmdvb2dsZS5wcm90b2J1Zi5GZWF0dXJlU2V0LlZpc2liaWxpdHlGZWF0",
            "dXJlLkRlZmF1bHRTeW1ib2xWaXNpYmlsaXR5QjaIAQKYAQGiAQ8SCkVYUE9S",
            "VF9BTEwYhAeiARUSEEVYUE9SVF9UT1BfTEVWRUwY6QeyAQMI6QcaoQEKEVZp",
            "c2liaWxpdHlGZWF0dXJlIoEBChdEZWZhdWx0U3ltYm9sVmlzaWJpbGl0eRIl",
            "CiFERUZBVUxUX1NZTUJPTF9WSVNJQklMSVRZX1VOS05PV04QABIOCgpFWFBP",
            "UlRfQUxMEAESFAoQRVhQT1JUX1RPUF9MRVZFTBACEg0KCUxPQ0FMX0FMTBAD",
            "EgoKBlNUUklDVBAESggIARCAgICAAiJcCg1GaWVsZFByZXNlbmNlEhoKFkZJ",
            "RUxEX1BSRVNFTkNFX1VOS05PV04QABIMCghFWFBMSUNJVBABEgwKCElNUExJ",
            "Q0lUEAISEwoPTEVHQUNZX1JFUVVJUkVEEAMiNwoIRW51bVR5cGUSFQoRRU5V",
            "TV9UWVBFX1VOS05PV04QABIICgRPUEVOEAESCgoGQ0xPU0VEEAIiVgoVUmVw",
            "ZWF0ZWRGaWVsZEVuY29kaW5nEiMKH1JFUEVBVEVEX0ZJRUxEX0VOQ09ESU5H",
            "X1VOS05PV04QABIKCgZQQUNLRUQQARIMCghFWFBBTkRFRBACIkkKDlV0ZjhW",
            "YWxpZGF0aW9uEhsKF1VURjhfVkFMSURBVElPTl9VTktOT1dOEAASCgoGVkVS",
            "SUZZEAISCAoETk9ORRADIgQIARABIlMKD01lc3NhZ2VFbmNvZGluZxIcChhN",
            "RVNTQUdFX0VOQ09ESU5HX1VOS05PV04QABITCg9MRU5HVEhfUFJFRklYRUQQ",
            "ARINCglERUxJTUlURUQQAiJICgpKc29uRm9ybWF0EhcKE0pTT05fRk9STUFU",
            "X1VOS05PV04QABIJCgVBTExPVxABEhYKEkxFR0FDWV9CRVNUX0VGRk9SVBAC",
            "IlcKEkVuZm9yY2VOYW1pbmdTdHlsZRIgChxFTkZPUkNFX05BTUlOR19TVFlM",
            "RV9VTktOT1dOEAASDQoJU1RZTEUyMDI0EAESEAoMU1RZTEVfTEVHQUNZEAIq",
            "BgjoBxCLTioGCItOEJBOKgYIkE4QkU5KBgjnBxDoByKYAwoSRmVhdHVyZVNl",
            "dERlZmF1bHRzEk4KCGRlZmF1bHRzGAEgAygLMjwuZ29vZ2xlLnByb3RvYnVm",
            "LkZlYXR1cmVTZXREZWZhdWx0cy5GZWF0dXJlU2V0RWRpdGlvbkRlZmF1bHQS",
            "MQoPbWluaW11bV9lZGl0aW9uGAQgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVk",
            "aXRpb24SMQoPbWF4aW11bV9lZGl0aW9uGAUgASgOMhguZ29vZ2xlLnByb3Rv",
            "YnVmLkVkaXRpb24aywEKGEZlYXR1cmVTZXRFZGl0aW9uRGVmYXVsdBIpCgdl",
            "ZGl0aW9uGAMgASgOMhguZ29vZ2xlLnByb3RvYnVmLkVkaXRpb24SOQoUb3Zl",
            "cnJpZGFibGVfZmVhdHVyZXMYBCABKAsyGy5nb29nbGUucHJvdG9idWYuRmVh",
            "dHVyZVNldBIzCg5maXhlZF9mZWF0dXJlcxgFIAEoCzIbLmdvb2dsZS5wcm90",
            "b2J1Zi5GZWF0dXJlU2V0SgQIARACSgQIAhADUghmZWF0dXJlcyLjAQoOU291",
            "cmNlQ29kZUluZm8SOgoIbG9jYXRpb24YASADKAsyKC5nb29nbGUucHJvdG9i",
            "dWYuU291cmNlQ29kZUluZm8uTG9jYXRpb24ahgEKCExvY2F0aW9uEhAKBHBh",
            "dGgYASADKAVCAhABEhAKBHNwYW4YAiADKAVCAhABEhgKEGxlYWRpbmdfY29t",
            "bWVudHMYAyABKAkSGQoRdHJhaWxpbmdfY29tbWVudHMYBCABKAkSIQoZbGVh",
            "ZGluZ19kZXRhY2hlZF9jb21tZW50cxgGIAMoCSoMCIDsyv8BEIHsyv8BIpwC",
            "ChFHZW5lcmF0ZWRDb2RlSW5mbxJBCgphbm5vdGF0aW9uGAEgAygLMi0uZ29v",
            "Z2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFubm90YXRpb24awwEK",
            "CkFubm90YXRpb24SEAoEcGF0aBgBIAMoBUICEAESEwoLc291cmNlX2ZpbGUY",
            "AiABKAkSDQoFYmVnaW4YAyABKAUSCwoDZW5kGAQgASgFEkgKCHNlbWFudGlj",
            "GAUgASgOMjYuZ29vZ2xlLnByb3RvYnVmLkdlbmVyYXRlZENvZGVJbmZvLkFu",
            "bm90YXRpb24uU2VtYW50aWMiKAoIU2VtYW50aWMSCAoETk9ORRAAEgcKA1NF",
            "VBABEgkKBUFMSUFTEAIqpwIKB0VkaXRpb24SEwoPRURJVElPTl9VTktOT1dO",
            "EAASEwoORURJVElPTl9MRUdBQ1kQhAcSEwoORURJVElPTl9QUk9UTzIQ5gcS",
            "EwoORURJVElPTl9QUk9UTzMQ5wcSEQoMRURJVElPTl8yMDIzEOgHEhEKDEVE",
            "SVRJT05fMjAyNBDpBxIXChNFRElUSU9OXzFfVEVTVF9PTkxZEAESFwoTRURJ",
            "VElPTl8yX1RFU1RfT05MWRACEh0KF0VESVRJT05fOTk5OTdfVEVTVF9PTkxZ",
            "EJ2NBhIdChdFRElUSU9OXzk5OTk4X1RFU1RfT05MWRCejQYSHQoXRURJVElP",
            "Tl85OTk5OV9URVNUX09OTFkQn40GEhMKC0VESVRJT05fTUFYEP////8HKlUK",
            "EFN5bWJvbFZpc2liaWxpdHkSFAoQVklTSUJJTElUWV9VTlNFVBAAEhQKEFZJ",
            "U0lCSUxJVFlfTE9DQUwQARIVChFWSVNJQklMSVRZX0VYUE9SVBACQn4KE2Nv",
            "bS5nb29nbGUucHJvdG9idWZCEERlc2NyaXB0b3JQcm90b3NIAVotZ29vZ2xl",
            "LmdvbGFuZy5vcmcvcHJvdG9idWYvdHlwZXMvZGVzY3JpcHRvcnBi+AEBogID",
            "R1BCqgIaR29vZ2xlLlByb3RvYnVmLlJlZmxlY3Rpb24="));
      descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData,
          new pbr::FileDescriptor[] { },
          new pbr::GeneratedClrTypeInfo(new[] {typeof(global::Google.Protobuf.Reflection.Edition), typeof(global::Google.Protobuf.Reflection.SymbolVisibility), }, 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", "OptionDependency", "MessageType", "EnumType", "Service", "Extension", "Options", "SourceCodeInfo", "Syntax", "Edition" }, 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", "Visibility" }, 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", "Declaration", "Features", "Verification" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration), global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration.Parser, new[]{ "Number", "FullName", "Type", "Reserved", "Repeated" }, 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", "Proto3Optional" }, 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", "Visibility" }, 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", "Deprecated", "CcEnableArenas", "ObjcClassPrefix", "CsharpNamespace", "SwiftPrefix", "PhpClassPrefix", "PhpNamespace", "PhpMetadataNamespace", "RubyPackage", "Features", "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", "DeprecatedLegacyJsonFieldConflicts", "Features", "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", "UnverifiedLazy", "Deprecated", "Weak", "DebugRedact", "Retention", "Targets", "EditionDefaults", "Features", "FeatureSupport", "UninterpretedOption" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.CType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.JSType), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention), typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault), global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault.Parser, new[]{ "Edition", "Value" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport), global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport.Parser, new[]{ "EditionIntroduced", "EditionDeprecated", "DeprecationWarning", "EditionRemoved" }, null, null, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.OneofOptions), global::Google.Protobuf.Reflection.OneofOptions.Parser, new[]{ "Features", "UninterpretedOption" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumOptions), global::Google.Protobuf.Reflection.EnumOptions.Parser, new[]{ "AllowAlias", "Deprecated", "DeprecatedLegacyJsonFieldConflicts", "Features", "UninterpretedOption" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.EnumValueOptions), global::Google.Protobuf.Reflection.EnumValueOptions.Parser, new[]{ "Deprecated", "Features", "DebugRedact", "FeatureSupport", "UninterpretedOption" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.ServiceOptions), global::Google.Protobuf.Reflection.ServiceOptions.Parser, new[]{ "Features", "Deprecated", "UninterpretedOption" }, null, null, null, null),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.MethodOptions), global::Google.Protobuf.Reflection.MethodOptions.Parser, new[]{ "Deprecated", "IdempotencyLevel", "Features", "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.FeatureSet), global::Google.Protobuf.Reflection.FeatureSet.Parser, new[]{ "FieldPresence", "EnumType", "RepeatedFieldEncoding", "Utf8Validation", "MessageEncoding", "JsonFormat", "EnforceNamingStyle", "DefaultSymbolVisibility" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence), typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType), typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding), typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation), typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding), typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat), typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle) }, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature), global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Parser, null, null, new[]{ typeof(global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility) }, null, null)}),
            new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FeatureSetDefaults), global::Google.Protobuf.Reflection.FeatureSetDefaults.Parser, new[]{ "Defaults", "MinimumEdition", "MaximumEdition" }, null, null, null, new pbr::GeneratedClrTypeInfo[] { new pbr::GeneratedClrTypeInfo(typeof(global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault), global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault.Parser, new[]{ "Edition", "OverridableFeatures", "FixedFeatures" }, 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", "Semantic" }, null, new[]{ typeof(global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic) }, null, null)})
          }));
    }
    #endregion

  }
  #region Enums
  /// <summary>
  /// The full set of known editions.
  /// </summary>
  public enum Edition {
    /// <summary>
    /// A placeholder for an unknown edition value.
    /// </summary>
    [pbr::OriginalName("EDITION_UNKNOWN")] Unknown = 0,
    /// <summary>
    /// A placeholder edition for specifying default behaviors *before* a feature
    /// was first introduced.  This is effectively an "infinite past".
    /// </summary>
    [pbr::OriginalName("EDITION_LEGACY")] Legacy = 900,
    /// <summary>
    /// Legacy syntax "editions".  These pre-date editions, but behave much like
    /// distinct editions.  These can't be used to specify the edition of proto
    /// files, but feature definitions must supply proto2/proto3 defaults for
    /// backwards compatibility.
    /// </summary>
    [pbr::OriginalName("EDITION_PROTO2")] Proto2 = 998,
    [pbr::OriginalName("EDITION_PROTO3")] Proto3 = 999,
    /// <summary>
    /// Editions that have been released.  The specific values are arbitrary and
    /// should not be depended on, but they will always be time-ordered for easy
    /// comparison.
    /// </summary>
    [pbr::OriginalName("EDITION_2023")] _2023 = 1000,
    [pbr::OriginalName("EDITION_2024")] _2024 = 1001,
    /// <summary>
    /// Placeholder editions for testing feature resolution.  These should not be
    /// used or relied on outside of tests.
    /// </summary>
    [pbr::OriginalName("EDITION_1_TEST_ONLY")] _1TestOnly = 1,
    [pbr::OriginalName("EDITION_2_TEST_ONLY")] _2TestOnly = 2,
    [pbr::OriginalName("EDITION_99997_TEST_ONLY")] _99997TestOnly = 99997,
    [pbr::OriginalName("EDITION_99998_TEST_ONLY")] _99998TestOnly = 99998,
    [pbr::OriginalName("EDITION_99999_TEST_ONLY")] _99999TestOnly = 99999,
    /// <summary>
    /// Placeholder for specifying unbounded edition support.  This should only
    /// ever be used by plugins that can expect to never require any changes to
    /// support a new edition.
    /// </summary>
    [pbr::OriginalName("EDITION_MAX")] Max = 2147483647,
  }

  /// <summary>
  /// Describes the 'visibility' of a symbol with respect to the proto import
  /// system. Symbols can only be imported when the visibility rules do not prevent
  /// it (ex: local symbols cannot be imported).  Visibility modifiers can only set
  /// on `message` and `enum` as they are the only types available to be referenced
  /// from other files.
  /// </summary>
  public enum SymbolVisibility {
    [pbr::OriginalName("VISIBILITY_UNSET")] VisibilityUnset = 0,
    [pbr::OriginalName("VISIBILITY_LOCAL")] VisibilityLocal = 1,
    [pbr::OriginalName("VISIBILITY_EXPORT")] VisibilityExport = 2,
  }

  #endregion

  #region Messages
  /// <summary>
  /// The protocol compiler can output a FileDescriptorSet containing the .proto
  /// files it parses.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FileDescriptorSet : pb::IExtendableMessage<FileDescriptorSet>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<FileDescriptorSet> _parser = new pb::MessageParser<FileDescriptorSet>(() => new FileDescriptorSet());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<FileDescriptorSet> _extensions;
    private pb::ExtensionSet<FileDescriptorSet> _Extensions { get { return _extensions; } }
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FileDescriptorSet> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[0]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FileDescriptorSet() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FileDescriptorSet(FileDescriptorSet other) : this() {
      file_ = other.file_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FileDescriptorProto> File {
      get { return file_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FileDescriptorSet);
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= file_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      file_.WriteTo(output, _repeated_file_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      file_.WriteTo(ref output, _repeated_file_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      size += file_.CalculateSize(_repeated_file_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(FileDescriptorSet other) {
      if (other == null) {
        return;
      }
      file_.Add(other.file_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 10: {
            file_.AddEntriesFrom(input, _repeated_file_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 10: {
            file_.AddEntriesFrom(ref input, _repeated_file_codec);
            break;
          }
        }
      }
    }
    #endif

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

  }

  /// <summary>
  /// Describes a complete .proto file.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FileDescriptorProto : pb::IMessage<FileDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<FileDescriptorProto> _parser = new pb::MessageParser<FileDescriptorProto>(() => new FileDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FileDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[1]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FileDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPackage {
      get { return package_ != null; }
    }
    /// <summary>Clears the value of the "package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<int> WeakDependency {
      get { return weakDependency_; }
    }

    /// <summary>Field number for the "option_dependency" field.</summary>
    public const int OptionDependencyFieldNumber = 15;
    private static readonly pb::FieldCodec<string> _repeated_optionDependency_codec
        = pb::FieldCodec.ForString(122);
    private readonly pbc::RepeatedField<string> optionDependency_ = new pbc::RepeatedField<string>();
    /// <summary>
    /// Names of files imported by this file purely for the purpose of providing
    /// option extensions. These are excluded from the dependency list above.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<string> OptionDependency {
      get { return optionDependency_; }
    }

    /// <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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FileOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

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

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

    private string syntax_;
    /// <summary>
    /// The syntax of the proto file.
    /// The supported values are "proto2", "proto3", and "editions".
    ///
    /// If `edition` is present, this value must be "editions".
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasSyntax {
      get { return syntax_ != null; }
    }
    /// <summary>Clears the value of the "syntax" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearSyntax() {
      syntax_ = null;
    }

    /// <summary>Field number for the "edition" field.</summary>
    public const int EditionFieldNumber = 14;
    private readonly static global::Google.Protobuf.Reflection.Edition EditionDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

    private global::Google.Protobuf.Reflection.Edition edition_;
    /// <summary>
    /// The edition of the proto file.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.Edition Edition {
      get { if ((_hasBits0 & 1) != 0) { return edition_; } else { return EditionDefaultValue; } }
      set {
        _hasBits0 |= 1;
        edition_ = value;
      }
    }
    /// <summary>Gets whether the "edition" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasEdition {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "edition" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearEdition() {
      _hasBits0 &= ~1;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FileDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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(!optionDependency_.Equals(other.optionDependency_)) 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;
      if (Edition != other.Edition) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 ^= optionDependency_.GetHashCode();
      hash ^= messageType_.GetHashCode();
      hash ^= enumType_.GetHashCode();
      hash ^= service_.GetHashCode();
      hash ^= extension_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (sourceCodeInfo_ != null) hash ^= SourceCodeInfo.GetHashCode();
      if (HasSyntax) hash ^= Syntax.GetHashCode();
      if (HasEdition) hash ^= Edition.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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 (options_ != null) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (sourceCodeInfo_ != null) {
        output.WriteRawTag(74);
        output.WriteMessage(SourceCodeInfo);
      }
      publicDependency_.WriteTo(output, _repeated_publicDependency_codec);
      weakDependency_.WriteTo(output, _repeated_weakDependency_codec);
      if (HasSyntax) {
        output.WriteRawTag(98);
        output.WriteString(Syntax);
      }
      if (HasEdition) {
        output.WriteRawTag(112);
        output.WriteEnum((int) Edition);
      }
      optionDependency_.WriteTo(output, _repeated_optionDependency_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasPackage) {
        output.WriteRawTag(18);
        output.WriteString(Package);
      }
      dependency_.WriteTo(ref output, _repeated_dependency_codec);
      messageType_.WriteTo(ref output, _repeated_messageType_codec);
      enumType_.WriteTo(ref output, _repeated_enumType_codec);
      service_.WriteTo(ref output, _repeated_service_codec);
      extension_.WriteTo(ref output, _repeated_extension_codec);
      if (options_ != null) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (sourceCodeInfo_ != null) {
        output.WriteRawTag(74);
        output.WriteMessage(SourceCodeInfo);
      }
      publicDependency_.WriteTo(ref output, _repeated_publicDependency_codec);
      weakDependency_.WriteTo(ref output, _repeated_weakDependency_codec);
      if (HasSyntax) {
        output.WriteRawTag(98);
        output.WriteString(Syntax);
      }
      if (HasEdition) {
        output.WriteRawTag(112);
        output.WriteEnum((int) Edition);
      }
      optionDependency_.WriteTo(ref output, _repeated_optionDependency_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 += optionDependency_.CalculateSize(_repeated_optionDependency_codec);
      size += messageType_.CalculateSize(_repeated_messageType_codec);
      size += enumType_.CalculateSize(_repeated_enumType_codec);
      size += service_.CalculateSize(_repeated_service_codec);
      size += extension_.CalculateSize(_repeated_extension_codec);
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (sourceCodeInfo_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(SourceCodeInfo);
      }
      if (HasSyntax) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Syntax);
      }
      if (HasEdition) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Edition);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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_);
      optionDependency_.Add(other.optionDependency_);
      messageType_.Add(other.messageType_);
      enumType_.Add(other.enumType_);
      service_.Add(other.service_);
      extension_.Add(other.extension_);
      if (other.options_ != null) {
        if (options_ == null) {
          Options = new global::Google.Protobuf.Reflection.FileOptions();
        }
        Options.MergeFrom(other.Options);
      }
      if (other.sourceCodeInfo_ != null) {
        if (sourceCodeInfo_ == null) {
          SourceCodeInfo = new global::Google.Protobuf.Reflection.SourceCodeInfo();
        }
        SourceCodeInfo.MergeFrom(other.SourceCodeInfo);
      }
      if (other.HasSyntax) {
        Syntax = other.Syntax;
      }
      if (other.HasEdition) {
        Edition = other.Edition;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Package = input.ReadString();
            break;
          }
          case 26: {
            dependency_.AddEntriesFrom(input, _repeated_dependency_codec);
            break;
          }
          case 34: {
            messageType_.AddEntriesFrom(input, _repeated_messageType_codec);
            break;
          }
          case 42: {
            enumType_.AddEntriesFrom(input, _repeated_enumType_codec);
            break;
          }
          case 50: {
            service_.AddEntriesFrom(input, _repeated_service_codec);
            break;
          }
          case 58: {
            extension_.AddEntriesFrom(input, _repeated_extension_codec);
            break;
          }
          case 66: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.FileOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 74: {
            if (sourceCodeInfo_ == null) {
              SourceCodeInfo = new global::Google.Protobuf.Reflection.SourceCodeInfo();
            }
            input.ReadMessage(SourceCodeInfo);
            break;
          }
          case 82:
          case 80: {
            publicDependency_.AddEntriesFrom(input, _repeated_publicDependency_codec);
            break;
          }
          case 90:
          case 88: {
            weakDependency_.AddEntriesFrom(input, _repeated_weakDependency_codec);
            break;
          }
          case 98: {
            Syntax = input.ReadString();
            break;
          }
          case 112: {
            Edition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
            break;
          }
          case 122: {
            optionDependency_.AddEntriesFrom(input, _repeated_optionDependency_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Package = input.ReadString();
            break;
          }
          case 26: {
            dependency_.AddEntriesFrom(ref input, _repeated_dependency_codec);
            break;
          }
          case 34: {
            messageType_.AddEntriesFrom(ref input, _repeated_messageType_codec);
            break;
          }
          case 42: {
            enumType_.AddEntriesFrom(ref input, _repeated_enumType_codec);
            break;
          }
          case 50: {
            service_.AddEntriesFrom(ref input, _repeated_service_codec);
            break;
          }
          case 58: {
            extension_.AddEntriesFrom(ref input, _repeated_extension_codec);
            break;
          }
          case 66: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.FileOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 74: {
            if (sourceCodeInfo_ == null) {
              SourceCodeInfo = new global::Google.Protobuf.Reflection.SourceCodeInfo();
            }
            input.ReadMessage(SourceCodeInfo);
            break;
          }
          case 82:
          case 80: {
            publicDependency_.AddEntriesFrom(ref input, _repeated_publicDependency_codec);
            break;
          }
          case 90:
          case 88: {
            weakDependency_.AddEntriesFrom(ref input, _repeated_weakDependency_codec);
            break;
          }
          case 98: {
            Syntax = input.ReadString();
            break;
          }
          case 112: {
            Edition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
            break;
          }
          case 122: {
            optionDependency_.AddEntriesFrom(ref input, _repeated_optionDependency_codec);
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Describes a message type.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class DescriptorProto : pb::IMessage<DescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<DescriptorProto> _parser = new pb::MessageParser<DescriptorProto>(() => new DescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<DescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[2]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public DescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.MessageOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    /// <summary>Field number for the "reserved_range" field.</summary>
    public const int ReservedRangeFieldNumber = 9;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> _repeated_reservedRange_codec
        = pb::FieldCodec.ForMessage(74, global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange> reservedRange_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.DescriptorProto.Types.ReservedRange>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<string> ReservedName {
      get { return reservedName_; }
    }

    /// <summary>Field number for the "visibility" field.</summary>
    public const int VisibilityFieldNumber = 11;
    private readonly static global::Google.Protobuf.Reflection.SymbolVisibility VisibilityDefaultValue = global::Google.Protobuf.Reflection.SymbolVisibility.VisibilityUnset;

    private global::Google.Protobuf.Reflection.SymbolVisibility visibility_;
    /// <summary>
    /// Support for `export` and `local` keywords on enums.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.SymbolVisibility Visibility {
      get { if ((_hasBits0 & 1) != 0) { return visibility_; } else { return VisibilityDefaultValue; } }
      set {
        _hasBits0 |= 1;
        visibility_ = value;
      }
    }
    /// <summary>Gets whether the "visibility" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasVisibility {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "visibility" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearVisibility() {
      _hasBits0 &= ~1;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as DescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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;
      if (Visibility != other.Visibility) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (options_ != null) hash ^= Options.GetHashCode();
      hash ^= reservedRange_.GetHashCode();
      hash ^= reservedName_.GetHashCode();
      if (HasVisibility) hash ^= Visibility.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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 (options_ != null) {
        output.WriteRawTag(58);
        output.WriteMessage(Options);
      }
      oneofDecl_.WriteTo(output, _repeated_oneofDecl_codec);
      reservedRange_.WriteTo(output, _repeated_reservedRange_codec);
      reservedName_.WriteTo(output, _repeated_reservedName_codec);
      if (HasVisibility) {
        output.WriteRawTag(88);
        output.WriteEnum((int) Visibility);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      field_.WriteTo(ref output, _repeated_field_codec);
      nestedType_.WriteTo(ref output, _repeated_nestedType_codec);
      enumType_.WriteTo(ref output, _repeated_enumType_codec);
      extensionRange_.WriteTo(ref output, _repeated_extensionRange_codec);
      extension_.WriteTo(ref output, _repeated_extension_codec);
      if (options_ != null) {
        output.WriteRawTag(58);
        output.WriteMessage(Options);
      }
      oneofDecl_.WriteTo(ref output, _repeated_oneofDecl_codec);
      reservedRange_.WriteTo(ref output, _repeated_reservedRange_codec);
      reservedName_.WriteTo(ref output, _repeated_reservedName_codec);
      if (HasVisibility) {
        output.WriteRawTag(88);
        output.WriteEnum((int) Visibility);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      size += reservedRange_.CalculateSize(_repeated_reservedRange_codec);
      size += reservedName_.CalculateSize(_repeated_reservedName_codec);
      if (HasVisibility) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Visibility);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.options_ != null) {
        if (options_ == null) {
          Options = new global::Google.Protobuf.Reflection.MessageOptions();
        }
        Options.MergeFrom(other.Options);
      }
      reservedRange_.Add(other.reservedRange_);
      reservedName_.Add(other.reservedName_);
      if (other.HasVisibility) {
        Visibility = other.Visibility;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            field_.AddEntriesFrom(input, _repeated_field_codec);
            break;
          }
          case 26: {
            nestedType_.AddEntriesFrom(input, _repeated_nestedType_codec);
            break;
          }
          case 34: {
            enumType_.AddEntriesFrom(input, _repeated_enumType_codec);
            break;
          }
          case 42: {
            extensionRange_.AddEntriesFrom(input, _repeated_extensionRange_codec);
            break;
          }
          case 50: {
            extension_.AddEntriesFrom(input, _repeated_extension_codec);
            break;
          }
          case 58: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.MessageOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 66: {
            oneofDecl_.AddEntriesFrom(input, _repeated_oneofDecl_codec);
            break;
          }
          case 74: {
            reservedRange_.AddEntriesFrom(input, _repeated_reservedRange_codec);
            break;
          }
          case 82: {
            reservedName_.AddEntriesFrom(input, _repeated_reservedName_codec);
            break;
          }
          case 88: {
            Visibility = (global::Google.Protobuf.Reflection.SymbolVisibility) input.ReadEnum();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            field_.AddEntriesFrom(ref input, _repeated_field_codec);
            break;
          }
          case 26: {
            nestedType_.AddEntriesFrom(ref input, _repeated_nestedType_codec);
            break;
          }
          case 34: {
            enumType_.AddEntriesFrom(ref input, _repeated_enumType_codec);
            break;
          }
          case 42: {
            extensionRange_.AddEntriesFrom(ref input, _repeated_extensionRange_codec);
            break;
          }
          case 50: {
            extension_.AddEntriesFrom(ref input, _repeated_extension_codec);
            break;
          }
          case 58: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.MessageOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 66: {
            oneofDecl_.AddEntriesFrom(ref input, _repeated_oneofDecl_codec);
            break;
          }
          case 74: {
            reservedRange_.AddEntriesFrom(ref input, _repeated_reservedRange_codec);
            break;
          }
          case 82: {
            reservedName_.AddEntriesFrom(ref input, _repeated_reservedName_codec);
            break;
          }
          case 88: {
            Visibility = (global::Google.Protobuf.Reflection.SymbolVisibility) input.ReadEnum();
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the DescriptorProto message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class ExtensionRange : pb::IMessage<ExtensionRange>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<ExtensionRange> _parser = new pb::MessageParser<ExtensionRange>(() => new ExtensionRange());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<ExtensionRange> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.DescriptorProto.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public ExtensionRange() {
          OnConstruction();
        }

        partial void OnConstruction();

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasStart {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "start" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.ExtensionRangeOptions Options {
          get { return options_; }
          set {
            options_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as ExtensionRange);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override int GetHashCode() {
          int hash = 1;
          if (HasStart) hash ^= Start.GetHashCode();
          if (HasEnd) hash ^= End.GetHashCode();
          if (options_ != null) hash ^= Options.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (options_ != null) {
            output.WriteRawTag(26);
            output.WriteMessage(Options);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (options_ != null) {
            output.WriteRawTag(26);
            output.WriteMessage(Options);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

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

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

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
              case 26: {
                if (options_ == null) {
                  Options = new global::Google.Protobuf.Reflection.ExtensionRangeOptions();
                }
                input.ReadMessage(Options);
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
              case 26: {
                if (options_ == null) {
                  Options = new global::Google.Protobuf.Reflection.ExtensionRangeOptions();
                }
                input.ReadMessage(Options);
                break;
              }
            }
          }
        }
        #endif

      }

      /// <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>
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class ReservedRange : pb::IMessage<ReservedRange>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<ReservedRange> _parser = new pb::MessageParser<ReservedRange>(() => new ReservedRange());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<ReservedRange> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.DescriptorProto.Descriptor.NestedTypes[1]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public ReservedRange() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public ReservedRange(ReservedRange other) : this() {
          _hasBits0 = other._hasBits0;
          start_ = other.start_;
          end_ = other.end_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasStart {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "start" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as ReservedRange);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class ExtensionRangeOptions : pb::IExtendableMessage<ExtensionRangeOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<ExtensionRangeOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[3]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ExtensionRangeOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ExtensionRangeOptions(ExtensionRangeOptions other) : this() {
      _hasBits0 = other._hasBits0;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      declaration_ = other.declaration_.Clone();
      features_ = other.features_ != null ? other.features_.Clone() : null;
      verification_ = other.verification_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    /// <summary>Field number for the "declaration" field.</summary>
    public const int DeclarationFieldNumber = 2;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration> _repeated_declaration_codec
        = pb::FieldCodec.ForMessage(18, global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration> declaration_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration>();
    /// <summary>
    /// For external users: DO NOT USE. We are in the process of open sourcing
    /// extension declaration and executing internal cleanups before it can be
    /// used externally.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.Declaration> Declaration {
      get { return declaration_; }
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 50;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

    /// <summary>Field number for the "verification" field.</summary>
    public const int VerificationFieldNumber = 3;
    private readonly static global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState VerificationDefaultValue = global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState.Unverified;

    private global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState verification_;
    /// <summary>
    /// The verification state of the range.
    /// TODO: flip the default to DECLARATION once all empty ranges
    /// are marked as UNVERIFIED.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState Verification {
      get { if ((_hasBits0 & 1) != 0) { return verification_; } else { return VerificationDefaultValue; } }
      set {
        _hasBits0 |= 1;
        verification_ = value;
      }
    }
    /// <summary>Gets whether the "verification" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasVerification {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "verification" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearVerification() {
      _hasBits0 &= ~1;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as ExtensionRangeOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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(!declaration_.Equals(other.declaration_)) return false;
      if (!object.Equals(Features, other.Features)) return false;
      if (Verification != other.Verification) return false;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= uninterpretedOption_.GetHashCode();
      hash ^= declaration_.GetHashCode();
      if (features_ != null) hash ^= Features.GetHashCode();
      if (HasVerification) hash ^= Verification.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      declaration_.WriteTo(output, _repeated_declaration_codec);
      if (HasVerification) {
        output.WriteRawTag(24);
        output.WriteEnum((int) Verification);
      }
      if (features_ != null) {
        output.WriteRawTag(146, 3);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      declaration_.WriteTo(ref output, _repeated_declaration_codec);
      if (HasVerification) {
        output.WriteRawTag(24);
        output.WriteEnum((int) Verification);
      }
      if (features_ != null) {
        output.WriteRawTag(146, 3);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      size += declaration_.CalculateSize(_repeated_declaration_codec);
      if (features_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      if (HasVerification) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Verification);
      }
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(ExtensionRangeOptions other) {
      if (other == null) {
        return;
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      declaration_.Add(other.declaration_);
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      if (other.HasVerification) {
        Verification = other.Verification;
      }
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 18: {
            declaration_.AddEntriesFrom(input, _repeated_declaration_codec);
            break;
          }
          case 24: {
            Verification = (global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState) input.ReadEnum();
            break;
          }
          case 402: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 18: {
            declaration_.AddEntriesFrom(ref input, _repeated_declaration_codec);
            break;
          }
          case 24: {
            Verification = (global::Google.Protobuf.Reflection.ExtensionRangeOptions.Types.VerificationState) input.ReadEnum();
            break;
          }
          case 402: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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);
    }

    #region Nested types
    /// <summary>Container for nested types declared in the ExtensionRangeOptions message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      /// <summary>
      /// The verification state of the extension range.
      /// </summary>
      public enum VerificationState {
        /// <summary>
        /// All the extensions of the range must be declared.
        /// </summary>
        [pbr::OriginalName("DECLARATION")] Declaration = 0,
        [pbr::OriginalName("UNVERIFIED")] Unverified = 1,
      }

      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class Declaration : pb::IMessage<Declaration>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<Declaration> _parser = new pb::MessageParser<Declaration>(() => new Declaration());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<Declaration> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.ExtensionRangeOptions.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public Declaration() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public Declaration(Declaration other) : this() {
          _hasBits0 = other._hasBits0;
          number_ = other.number_;
          fullName_ = other.fullName_;
          type_ = other.type_;
          reserved_ = other.reserved_;
          repeated_ = other.repeated_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public Declaration Clone() {
          return new Declaration(this);
        }

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

        private int number_;
        /// <summary>
        /// The extension number declared within the extension range.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasNumber {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "number" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearNumber() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "full_name" field.</summary>
        public const int FullNameFieldNumber = 2;
        private readonly static string FullNameDefaultValue = "";

        private string fullName_;
        /// <summary>
        /// The fully-qualified name of the extension field. There must be a leading
        /// dot in front of the full name.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public string FullName {
          get { return fullName_ ?? FullNameDefaultValue; }
          set {
            fullName_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "full_name" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasFullName {
          get { return fullName_ != null; }
        }
        /// <summary>Clears the value of the "full_name" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearFullName() {
          fullName_ = null;
        }

        /// <summary>Field number for the "type" field.</summary>
        public const int TypeFieldNumber = 3;
        private readonly static string TypeDefaultValue = "";

        private string type_;
        /// <summary>
        /// The fully-qualified type name of the extension field. Unlike
        /// Metadata.type, Declaration.type must have a leading dot for messages
        /// and enums.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public string Type {
          get { return type_ ?? TypeDefaultValue; }
          set {
            type_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "type" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasType {
          get { return type_ != null; }
        }
        /// <summary>Clears the value of the "type" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearType() {
          type_ = null;
        }

        /// <summary>Field number for the "reserved" field.</summary>
        public const int ReservedFieldNumber = 5;
        private readonly static bool ReservedDefaultValue = false;

        private bool reserved_;
        /// <summary>
        /// If true, indicates that the number is reserved in the extension range,
        /// and any extension field with the number will fail to compile. Set this
        /// when a declared extension field is deleted.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Reserved {
          get { if ((_hasBits0 & 2) != 0) { return reserved_; } else { return ReservedDefaultValue; } }
          set {
            _hasBits0 |= 2;
            reserved_ = value;
          }
        }
        /// <summary>Gets whether the "reserved" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasReserved {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "reserved" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearReserved() {
          _hasBits0 &= ~2;
        }

        /// <summary>Field number for the "repeated" field.</summary>
        public const int RepeatedFieldNumber = 6;
        private readonly static bool RepeatedDefaultValue = false;

        private bool repeated_;
        /// <summary>
        /// If true, indicates that the extension must be defined as repeated.
        /// Otherwise the extension must be defined as optional.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Repeated {
          get { if ((_hasBits0 & 4) != 0) { return repeated_; } else { return RepeatedDefaultValue; } }
          set {
            _hasBits0 |= 4;
            repeated_ = value;
          }
        }
        /// <summary>Gets whether the "repeated" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasRepeated {
          get { return (_hasBits0 & 4) != 0; }
        }
        /// <summary>Clears the value of the "repeated" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearRepeated() {
          _hasBits0 &= ~4;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as Declaration);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Equals(Declaration other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Number != other.Number) return false;
          if (FullName != other.FullName) return false;
          if (Type != other.Type) return false;
          if (Reserved != other.Reserved) return false;
          if (Repeated != other.Repeated) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override int GetHashCode() {
          int hash = 1;
          if (HasNumber) hash ^= Number.GetHashCode();
          if (HasFullName) hash ^= FullName.GetHashCode();
          if (HasType) hash ^= Type.GetHashCode();
          if (HasReserved) hash ^= Reserved.GetHashCode();
          if (HasRepeated) hash ^= Repeated.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasNumber) {
            output.WriteRawTag(8);
            output.WriteInt32(Number);
          }
          if (HasFullName) {
            output.WriteRawTag(18);
            output.WriteString(FullName);
          }
          if (HasType) {
            output.WriteRawTag(26);
            output.WriteString(Type);
          }
          if (HasReserved) {
            output.WriteRawTag(40);
            output.WriteBool(Reserved);
          }
          if (HasRepeated) {
            output.WriteRawTag(48);
            output.WriteBool(Repeated);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasNumber) {
            output.WriteRawTag(8);
            output.WriteInt32(Number);
          }
          if (HasFullName) {
            output.WriteRawTag(18);
            output.WriteString(FullName);
          }
          if (HasType) {
            output.WriteRawTag(26);
            output.WriteString(Type);
          }
          if (HasReserved) {
            output.WriteRawTag(40);
            output.WriteBool(Reserved);
          }
          if (HasRepeated) {
            output.WriteRawTag(48);
            output.WriteBool(Repeated);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public int CalculateSize() {
          int size = 0;
          if (HasNumber) {
            size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
          }
          if (HasFullName) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(FullName);
          }
          if (HasType) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(Type);
          }
          if (HasReserved) {
            size += 1 + 1;
          }
          if (HasRepeated) {
            size += 1 + 1;
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(Declaration other) {
          if (other == null) {
            return;
          }
          if (other.HasNumber) {
            Number = other.Number;
          }
          if (other.HasFullName) {
            FullName = other.FullName;
          }
          if (other.HasType) {
            Type = other.Type;
          }
          if (other.HasReserved) {
            Reserved = other.Reserved;
          }
          if (other.HasRepeated) {
            Repeated = other.Repeated;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Number = input.ReadInt32();
                break;
              }
              case 18: {
                FullName = input.ReadString();
                break;
              }
              case 26: {
                Type = input.ReadString();
                break;
              }
              case 40: {
                Reserved = input.ReadBool();
                break;
              }
              case 48: {
                Repeated = input.ReadBool();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 8: {
                Number = input.ReadInt32();
                break;
              }
              case 18: {
                FullName = input.ReadString();
                break;
              }
              case 26: {
                Type = input.ReadString();
                break;
              }
              case 40: {
                Reserved = input.ReadBool();
                break;
              }
              case 48: {
                Repeated = input.ReadBool();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  /// <summary>
  /// Describes a field within a message.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FieldDescriptorProto : pb::IMessage<FieldDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<FieldDescriptorProto> _parser = new pb::MessageParser<FieldDescriptorProto>(() => new FieldDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FieldDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[4]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FieldDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.options_ != null ? other.options_.Clone() : null;
      proto3Optional_ = other.proto3Optional_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasNumber {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "number" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasLabel {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "label" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasType {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasTypeName {
      get { return typeName_ != null; }
    }
    /// <summary>Clears the value of the "type_name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasExtendee {
      get { return extendee_ != null; }
    }
    /// <summary>Clears the value of the "extendee" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDefaultValue {
      get { return defaultValue_ != null; }
    }
    /// <summary>Clears the value of the "default_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasOneofIndex {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "oneof_index" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJsonName {
      get { return jsonName_ != null; }
    }
    /// <summary>Clears the value of the "json_name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FieldOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    /// <summary>Field number for the "proto3_optional" field.</summary>
    public const int Proto3OptionalFieldNumber = 17;
    private readonly static bool Proto3OptionalDefaultValue = false;

    private bool proto3Optional_;
    /// <summary>
    /// If true, this is a proto3 "optional". When a proto3 field is optional, it
    /// tracks presence regardless of field type.
    ///
    /// When proto3_optional is true, this field must belong to a oneof to signal
    /// to old proto3 clients that presence is tracked for this field. This oneof
    /// is known as a "synthetic" oneof, and this field must be its sole member
    /// (each proto3 optional field gets its own synthetic oneof). Synthetic oneofs
    /// exist in the descriptor only, and do not generate any API. Synthetic oneofs
    /// must be ordered after all "real" oneofs.
    ///
    /// For message fields, proto3_optional doesn't create any semantic change,
    /// since non-repeated message fields always track presence. However it still
    /// indicates the semantic detail of whether the user wrote "optional" or not.
    /// This can be useful for round-tripping the .proto file. For consistency we
    /// give message fields a synthetic oneof also, even though it is not required
    /// to track presence. This is especially important because the parser can't
    /// tell if a field is a message or an enum, so it must always create a
    /// synthetic oneof.
    ///
    /// Proto2 optional fields do not set this flag, because they already indicate
    /// optional with `LABEL_OPTIONAL`.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Proto3Optional {
      get { if ((_hasBits0 & 16) != 0) { return proto3Optional_; } else { return Proto3OptionalDefaultValue; } }
      set {
        _hasBits0 |= 16;
        proto3Optional_ = value;
      }
    }
    /// <summary>Gets whether the "proto3_optional" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasProto3Optional {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "proto3_optional" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearProto3Optional() {
      _hasBits0 &= ~16;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FieldDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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;
      if (Proto3Optional != other.Proto3Optional) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (options_ != null) hash ^= Options.GetHashCode();
      if (HasProto3Optional) hash ^= Proto3Optional.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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 (options_ != null) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (HasOneofIndex) {
        output.WriteRawTag(72);
        output.WriteInt32(OneofIndex);
      }
      if (HasJsonName) {
        output.WriteRawTag(82);
        output.WriteString(JsonName);
      }
      if (HasProto3Optional) {
        output.WriteRawTag(136, 1);
        output.WriteBool(Proto3Optional);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext 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 (options_ != null) {
        output.WriteRawTag(66);
        output.WriteMessage(Options);
      }
      if (HasOneofIndex) {
        output.WriteRawTag(72);
        output.WriteInt32(OneofIndex);
      }
      if (HasJsonName) {
        output.WriteRawTag(82);
        output.WriteString(JsonName);
      }
      if (HasProto3Optional) {
        output.WriteRawTag(136, 1);
        output.WriteBool(Proto3Optional);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (HasProto3Optional) {
        size += 2 + 1;
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.options_ != null) {
        if (options_ == null) {
          Options = new global::Google.Protobuf.Reflection.FieldOptions();
        }
        Options.MergeFrom(other.Options);
      }
      if (other.HasProto3Optional) {
        Proto3Optional = other.Proto3Optional;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Extendee = input.ReadString();
            break;
          }
          case 24: {
            Number = input.ReadInt32();
            break;
          }
          case 32: {
            Label = (global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) input.ReadEnum();
            break;
          }
          case 40: {
            Type = (global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type) input.ReadEnum();
            break;
          }
          case 50: {
            TypeName = input.ReadString();
            break;
          }
          case 58: {
            DefaultValue = input.ReadString();
            break;
          }
          case 66: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.FieldOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 72: {
            OneofIndex = input.ReadInt32();
            break;
          }
          case 82: {
            JsonName = input.ReadString();
            break;
          }
          case 136: {
            Proto3Optional = input.ReadBool();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            Extendee = input.ReadString();
            break;
          }
          case 24: {
            Number = input.ReadInt32();
            break;
          }
          case 32: {
            Label = (global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Label) input.ReadEnum();
            break;
          }
          case 40: {
            Type = (global::Google.Protobuf.Reflection.FieldDescriptorProto.Types.Type) input.ReadEnum();
            break;
          }
          case 50: {
            TypeName = input.ReadString();
            break;
          }
          case 58: {
            DefaultValue = input.ReadString();
            break;
          }
          case 66: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.FieldOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 72: {
            OneofIndex = input.ReadInt32();
            break;
          }
          case 82: {
            JsonName = input.ReadString();
            break;
          }
          case 136: {
            Proto3Optional = input.ReadBool();
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the FieldDescriptorProto message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 after google.protobuf. However, Proto3
        /// implementations should still be able to parse the group wire format and
        /// treat group fields as unknown fields.  In Editions, the group wire format
        /// can be enabled via the `message_encoding` feature.
        /// </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_REPEATED")] Repeated = 3,
        /// <summary>
        /// The required label is only allowed in google.protobuf.  In proto3 and Editions
        /// it's explicitly prohibited.  In Editions, the `field_presence` feature
        /// can be used to get this behavior.
        /// </summary>
        [pbr::OriginalName("LABEL_REQUIRED")] Required = 2,
      }

    }
    #endregion

  }

  /// <summary>
  /// Describes a oneof.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class OneofDescriptorProto : pb::IMessage<OneofDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<OneofDescriptorProto> _parser = new pb::MessageParser<OneofDescriptorProto>(() => new OneofDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<OneofDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[5]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public OneofDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.OneofOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as OneofDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasName) hash ^= Name.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (options_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (options_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.OneofOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.OneofOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Describes an enum type.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class EnumDescriptorProto : pb::IMessage<EnumDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<EnumDescriptorProto> _parser = new pb::MessageParser<EnumDescriptorProto>(() => new EnumDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<EnumDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[6]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumDescriptorProto(EnumDescriptorProto other) : this() {
      _hasBits0 = other._hasBits0;
      name_ = other.name_;
      value_ = other.value_.Clone();
      options_ = other.options_ != null ? other.options_.Clone() : null;
      reservedRange_ = other.reservedRange_.Clone();
      reservedName_ = other.reservedName_.Clone();
      visibility_ = other.visibility_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.EnumOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

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

    /// <summary>Field number for the "visibility" field.</summary>
    public const int VisibilityFieldNumber = 6;
    private readonly static global::Google.Protobuf.Reflection.SymbolVisibility VisibilityDefaultValue = global::Google.Protobuf.Reflection.SymbolVisibility.VisibilityUnset;

    private global::Google.Protobuf.Reflection.SymbolVisibility visibility_;
    /// <summary>
    /// Support for `export` and `local` keywords on enums.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.SymbolVisibility Visibility {
      get { if ((_hasBits0 & 1) != 0) { return visibility_; } else { return VisibilityDefaultValue; } }
      set {
        _hasBits0 |= 1;
        visibility_ = value;
      }
    }
    /// <summary>Gets whether the "visibility" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasVisibility {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "visibility" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearVisibility() {
      _hasBits0 &= ~1;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as EnumDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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;
      if (Visibility != other.Visibility) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasName) hash ^= Name.GetHashCode();
      hash ^= value_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      hash ^= reservedRange_.GetHashCode();
      hash ^= reservedName_.GetHashCode();
      if (HasVisibility) hash ^= Visibility.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      value_.WriteTo(output, _repeated_value_codec);
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      reservedRange_.WriteTo(output, _repeated_reservedRange_codec);
      reservedName_.WriteTo(output, _repeated_reservedName_codec);
      if (HasVisibility) {
        output.WriteRawTag(48);
        output.WriteEnum((int) Visibility);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      value_.WriteTo(ref output, _repeated_value_codec);
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      reservedRange_.WriteTo(ref output, _repeated_reservedRange_codec);
      reservedName_.WriteTo(ref output, _repeated_reservedName_codec);
      if (HasVisibility) {
        output.WriteRawTag(48);
        output.WriteEnum((int) Visibility);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      size += value_.CalculateSize(_repeated_value_codec);
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      size += reservedRange_.CalculateSize(_repeated_reservedRange_codec);
      size += reservedName_.CalculateSize(_repeated_reservedName_codec);
      if (HasVisibility) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Visibility);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(EnumDescriptorProto other) {
      if (other == null) {
        return;
      }
      if (other.HasName) {
        Name = other.Name;
      }
      value_.Add(other.value_);
      if (other.options_ != null) {
        if (options_ == null) {
          Options = new global::Google.Protobuf.Reflection.EnumOptions();
        }
        Options.MergeFrom(other.Options);
      }
      reservedRange_.Add(other.reservedRange_);
      reservedName_.Add(other.reservedName_);
      if (other.HasVisibility) {
        Visibility = other.Visibility;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            value_.AddEntriesFrom(input, _repeated_value_codec);
            break;
          }
          case 26: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.EnumOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 34: {
            reservedRange_.AddEntriesFrom(input, _repeated_reservedRange_codec);
            break;
          }
          case 42: {
            reservedName_.AddEntriesFrom(input, _repeated_reservedName_codec);
            break;
          }
          case 48: {
            Visibility = (global::Google.Protobuf.Reflection.SymbolVisibility) input.ReadEnum();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            value_.AddEntriesFrom(ref input, _repeated_value_codec);
            break;
          }
          case 26: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.EnumOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 34: {
            reservedRange_.AddEntriesFrom(ref input, _repeated_reservedRange_codec);
            break;
          }
          case 42: {
            reservedName_.AddEntriesFrom(ref input, _repeated_reservedName_codec);
            break;
          }
          case 48: {
            Visibility = (global::Google.Protobuf.Reflection.SymbolVisibility) input.ReadEnum();
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the EnumDescriptorProto message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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>
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class EnumReservedRange : pb::IMessage<EnumReservedRange>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<EnumReservedRange> _parser = new pb::MessageParser<EnumReservedRange>(() => new EnumReservedRange());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<EnumReservedRange> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.EnumDescriptorProto.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public EnumReservedRange() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public EnumReservedRange(EnumReservedRange other) : this() {
          _hasBits0 = other._hasBits0;
          start_ = other.start_;
          end_ = other.end_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasStart {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "start" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as EnumReservedRange);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasStart) {
            output.WriteRawTag(8);
            output.WriteInt32(Start);
          }
          if (HasEnd) {
            output.WriteRawTag(16);
            output.WriteInt32(End);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 8: {
                Start = input.ReadInt32();
                break;
              }
              case 16: {
                End = input.ReadInt32();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  /// <summary>
  /// Describes a value within an enum.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class EnumValueDescriptorProto : pb::IMessage<EnumValueDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<EnumValueDescriptorProto> _parser = new pb::MessageParser<EnumValueDescriptorProto>(() => new EnumValueDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<EnumValueDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[7]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumValueDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasNumber {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "number" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.EnumValueOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as EnumValueDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasName) hash ^= Name.GetHashCode();
      if (HasNumber) hash ^= Number.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasNumber) {
        output.WriteRawTag(16);
        output.WriteInt32(Number);
      }
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      if (HasNumber) {
        output.WriteRawTag(16);
        output.WriteInt32(Number);
      }
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasName) {
        size += 1 + pb::CodedOutputStream.ComputeStringSize(Name);
      }
      if (HasNumber) {
        size += 1 + pb::CodedOutputStream.ComputeInt32Size(Number);
      }
      if (options_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Options);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 16: {
            Number = input.ReadInt32();
            break;
          }
          case 26: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.EnumValueOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 16: {
            Number = input.ReadInt32();
            break;
          }
          case 26: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.EnumValueOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Describes a service.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class ServiceDescriptorProto : pb::IMessage<ServiceDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<ServiceDescriptorProto> _parser = new pb::MessageParser<ServiceDescriptorProto>(() => new ServiceDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<ServiceDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[8]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ServiceDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.ServiceOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as ServiceDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasName) hash ^= Name.GetHashCode();
      hash ^= method_.GetHashCode();
      if (options_ != null) hash ^= Options.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      method_.WriteTo(output, _repeated_method_codec);
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasName) {
        output.WriteRawTag(10);
        output.WriteString(Name);
      }
      method_.WriteTo(ref output, _repeated_method_codec);
      if (options_ != null) {
        output.WriteRawTag(26);
        output.WriteMessage(Options);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            method_.AddEntriesFrom(input, _repeated_method_codec);
            break;
          }
          case 26: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.ServiceOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            method_.AddEntriesFrom(ref input, _repeated_method_codec);
            break;
          }
          case 26: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.ServiceOptions();
            }
            input.ReadMessage(Options);
            break;
          }
        }
      }
    }
    #endif

  }

  /// <summary>
  /// Describes a method of a service.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class MethodDescriptorProto : pb::IMessage<MethodDescriptorProto>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<MethodDescriptorProto> _parser = new pb::MessageParser<MethodDescriptorProto>(() => new MethodDescriptorProto());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<MethodDescriptorProto> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[9]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public MethodDescriptorProto() {
      OnConstruction();
    }

    partial void OnConstruction();

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasName {
      get { return name_ != null; }
    }
    /// <summary>Clears the value of the "name" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasInputType {
      get { return inputType_ != null; }
    }
    /// <summary>Clears the value of the "input_type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasOutputType {
      get { return outputType_ != null; }
    }
    /// <summary>Clears the value of the "output_type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.MethodOptions Options {
      get { return options_; }
      set {
        options_ = value;
      }
    }

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

    private bool clientStreaming_;
    /// <summary>
    /// Identifies if client streams multiple client messages
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasClientStreaming {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "client_streaming" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasServerStreaming {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "server_streaming" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearServerStreaming() {
      _hasBits0 &= ~2;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as MethodDescriptorProto);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasName) hash ^= Name.GetHashCode();
      if (HasInputType) hash ^= InputType.GetHashCode();
      if (HasOutputType) hash ^= OutputType.GetHashCode();
      if (options_ != null) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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 (options_ != null) {
        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);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext 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 (options_ != null) {
        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(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (options_ != null) {
        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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.options_ != null) {
        if (options_ == null) {
          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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            InputType = input.ReadString();
            break;
          }
          case 26: {
            OutputType = input.ReadString();
            break;
          }
          case 34: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.MethodOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 40: {
            ClientStreaming = input.ReadBool();
            break;
          }
          case 48: {
            ServerStreaming = input.ReadBool();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            Name = input.ReadString();
            break;
          }
          case 18: {
            InputType = input.ReadString();
            break;
          }
          case 26: {
            OutputType = input.ReadString();
            break;
          }
          case 34: {
            if (options_ == null) {
              Options = new global::Google.Protobuf.Reflection.MethodOptions();
            }
            input.ReadMessage(Options);
            break;
          }
          case 40: {
            ClientStreaming = input.ReadBool();
            break;
          }
          case 48: {
            ServerStreaming = input.ReadBool();
            break;
          }
        }
      }
    }
    #endif

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FileOptions : pb::IExtendableMessage<FileOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FileOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[10]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FileOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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_;
      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_;
      features_ = other.features_ != null ? other.features_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJavaPackage {
      get { return javaPackage_ != null; }
    }
    /// <summary>Clears the value of the "java_package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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>
    /// Controls the name of the wrapper Java class generated for the .proto file.
    /// That class will always contain the .proto file's getDescriptor() method as
    /// well as any top-level extensions defined in the .proto file.
    /// If java_multiple_files is disabled, then all the other classes from the
    /// .proto file will be nested inside the single wrapper outer class.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJavaOuterClassname {
      get { return javaOuterClassname_ != null; }
    }
    /// <summary>Clears the value of the "java_outer_classname" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 enabled, 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 wrapper class
    /// named by java_outer_classname.  However, the wrapper 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJavaMultipleFiles {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "java_multiple_files" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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>
    /// A proto2 file can set this to true to opt in to UTF-8 checking for Java,
    /// which will throw an exception if invalid UTF-8 is parsed from the wire or
    /// assigned to a string field.
    ///
    /// TODO: clarify exactly what kinds of field types this option
    /// applies to, and update these docs accordingly.
    ///
    /// Proto3 files already perform these checks. Setting the option explicitly to
    /// false has no effect: it cannot be used to opt proto3 files out of UTF-8
    /// checks.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJavaStringCheckUtf8 {
      get { return (_hasBits0 & 128) != 0; }
    }
    /// <summary>Clears the value of the "java_string_check_utf8" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasOptimizeFor {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "optimize_for" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasGoPackage {
      get { return goPackage_ != null; }
    }
    /// <summary>Clears the value of the "go_package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasCcGenericServices {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "cc_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJavaGenericServices {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "java_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPyGenericServices {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "py_generic_services" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearPyGenericServices() {
      _hasBits0 &= ~16;
    }

    /// <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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 64) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 = true;

    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasCcEnableArenas {
      get { return (_hasBits0 & 256) != 0; }
    }
    /// <summary>Clears the value of the "cc_enable_arenas" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasObjcClassPrefix {
      get { return objcClassPrefix_ != null; }
    }
    /// <summary>Clears the value of the "objc_class_prefix" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasCsharpNamespace {
      get { return csharpNamespace_ != null; }
    }
    /// <summary>Clears the value of the "csharp_namespace" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasSwiftPrefix {
      get { return swiftPrefix_ != null; }
    }
    /// <summary>Clears the value of the "swift_prefix" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPhpClassPrefix {
      get { return phpClassPrefix_ != null; }
    }
    /// <summary>Clears the value of the "php_class_prefix" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPhpNamespace {
      get { return phpNamespace_ != null; }
    }
    /// <summary>Clears the value of the "php_namespace" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPhpMetadataNamespace {
      get { return phpMetadataNamespace_ != null; }
    }
    /// <summary>Clears the value of the "php_metadata_namespace" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasRubyPackage {
      get { return rubyPackage_ != null; }
    }
    /// <summary>Clears the value of the "ruby_package" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearRubyPackage() {
      rubyPackage_ = null;
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 50;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FileOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (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 (!object.Equals(Features, other.Features)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (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();
      if (features_ != null) hash ^= Features.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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 (HasPhpMetadataNamespace) {
        output.WriteRawTag(226, 2);
        output.WriteString(PhpMetadataNamespace);
      }
      if (HasRubyPackage) {
        output.WriteRawTag(234, 2);
        output.WriteString(RubyPackage);
      }
      if (features_ != null) {
        output.WriteRawTag(146, 3);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext 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 (HasPhpMetadataNamespace) {
        output.WriteRawTag(226, 2);
        output.WriteString(PhpMetadataNamespace);
      }
      if (HasRubyPackage) {
        output.WriteRawTag(234, 2);
        output.WriteString(RubyPackage);
      }
      if (features_ != null) {
        output.WriteRawTag(146, 3);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (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);
      }
      if (features_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.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;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      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 354: {
            PhpMetadataNamespace = input.ReadString();
            break;
          }
          case 362: {
            RubyPackage = input.ReadString();
            break;
          }
          case 402: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref 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 354: {
            PhpMetadataNamespace = input.ReadString();
            break;
          }
          case 362: {
            RubyPackage = input.ReadString();
            break;
          }
          case 402: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class MessageOptions : pb::IExtendableMessage<MessageOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<MessageOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[11]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public MessageOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public MessageOptions(MessageOptions other) : this() {
      _hasBits0 = other._hasBits0;
      messageSetWireFormat_ = other.messageSetWireFormat_;
      noStandardDescriptorAccessor_ = other.noStandardDescriptorAccessor_;
      deprecated_ = other.deprecated_;
      mapEntry_ = other.mapEntry_;
      deprecatedLegacyJsonFieldConflicts_ = other.deprecatedLegacyJsonFieldConflicts_;
      features_ = other.features_ != null ? other.features_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasMessageSetWireFormat {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "message_set_wire_format" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasNoStandardDescriptorAccessor {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "no_standard_descriptor_accessor" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasMapEntry {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "map_entry" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearMapEntry() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "deprecated_legacy_json_field_conflicts" field.</summary>
    public const int DeprecatedLegacyJsonFieldConflictsFieldNumber = 11;
    private readonly static bool DeprecatedLegacyJsonFieldConflictsDefaultValue = false;

    private bool deprecatedLegacyJsonFieldConflicts_;
    /// <summary>
    /// Enable the legacy handling of JSON field name conflicts.  This lowercases
    /// and strips underscored from the fields before comparison in proto3 only.
    /// The new behavior takes `json_name` into account and applies to proto2 as
    /// well.
    ///
    /// This should only be used as a temporary measure against broken builds due
    /// to the change in behavior for JSON field name conflicts.
    ///
    /// TODO This is legacy behavior we plan to remove once downstream
    /// teams have had time to migrate.
    /// </summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool DeprecatedLegacyJsonFieldConflicts {
      get { if ((_hasBits0 & 16) != 0) { return deprecatedLegacyJsonFieldConflicts_; } else { return DeprecatedLegacyJsonFieldConflictsDefaultValue; } }
      set {
        _hasBits0 |= 16;
        deprecatedLegacyJsonFieldConflicts_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated_legacy_json_field_conflicts" field is set</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecatedLegacyJsonFieldConflicts {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "deprecated_legacy_json_field_conflicts" field</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDeprecatedLegacyJsonFieldConflicts() {
      _hasBits0 &= ~16;
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 12;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as MessageOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (DeprecatedLegacyJsonFieldConflicts != other.DeprecatedLegacyJsonFieldConflicts) return false;
      if (!object.Equals(Features, other.Features)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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();
      if (HasDeprecatedLegacyJsonFieldConflicts) hash ^= DeprecatedLegacyJsonFieldConflicts.GetHashCode();
      if (features_ != null) hash ^= Features.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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);
      }
      if (HasDeprecatedLegacyJsonFieldConflicts) {
        output.WriteRawTag(88);
        output.WriteBool(DeprecatedLegacyJsonFieldConflicts);
      }
      if (features_ != null) {
        output.WriteRawTag(98);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext 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);
      }
      if (HasDeprecatedLegacyJsonFieldConflicts) {
        output.WriteRawTag(88);
        output.WriteBool(DeprecatedLegacyJsonFieldConflicts);
      }
      if (features_ != null) {
        output.WriteRawTag(98);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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;
      }
      if (HasDeprecatedLegacyJsonFieldConflicts) {
        size += 1 + 1;
      }
      if (features_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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;
      }
      if (other.HasDeprecatedLegacyJsonFieldConflicts) {
        DeprecatedLegacyJsonFieldConflicts = other.DeprecatedLegacyJsonFieldConflicts;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      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 88: {
            DeprecatedLegacyJsonFieldConflicts = input.ReadBool();
            break;
          }
          case 98: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref 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 88: {
            DeprecatedLegacyJsonFieldConflicts = input.ReadBool();
            break;
          }
          case 98: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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);
    }

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FieldOptions : pb::IExtendableMessage<FieldOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FieldOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[12]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FieldOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FieldOptions(FieldOptions other) : this() {
      _hasBits0 = other._hasBits0;
      ctype_ = other.ctype_;
      packed_ = other.packed_;
      jstype_ = other.jstype_;
      lazy_ = other.lazy_;
      unverifiedLazy_ = other.unverifiedLazy_;
      deprecated_ = other.deprecated_;
      weak_ = other.weak_;
      debugRedact_ = other.debugRedact_;
      retention_ = other.retention_;
      targets_ = other.targets_.Clone();
      editionDefaults_ = other.editionDefaults_.Clone();
      features_ = other.features_ != null ? other.features_.Clone() : null;
      featureSupport_ = other.featureSupport_ != null ? other.featureSupport_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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>
    /// NOTE: ctype is deprecated. Use `features.(pb.cpp).string_type` instead.
    /// 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 only implemented to support use of
    /// [ctype=CORD] and [ctype=STRING] (the default) on non-repeated fields of
    /// type "bytes" in the open source release.
    /// TODO: make ctype actually deprecated.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasCtype {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "ctype" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.  This option is prohibited in
    /// Editions, but the `repeated_field_encoding` feature can be used to control
    /// the behavior.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPacked {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "packed" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJstype {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "jstype" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 lazy message fields are still eagerly verified to check
    /// ill-formed wireformat or missing required fields. Calling IsInitialized()
    /// on the outer message would fail if the inner message has missing required
    /// fields. Failed verification would result in parsing failure (except when
    /// uninitialized messages are acceptable).
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasLazy {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "lazy" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearLazy() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "unverified_lazy" field.</summary>
    public const int UnverifiedLazyFieldNumber = 15;
    private readonly static bool UnverifiedLazyDefaultValue = false;

    private bool unverifiedLazy_;
    /// <summary>
    /// unverified_lazy does no correctness checks on the byte stream. This should
    /// only be used where lazy with verification is prohibitive for performance
    /// reasons.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool UnverifiedLazy {
      get { if ((_hasBits0 & 64) != 0) { return unverifiedLazy_; } else { return UnverifiedLazyDefaultValue; } }
      set {
        _hasBits0 |= 64;
        unverifiedLazy_ = value;
      }
    }
    /// <summary>Gets whether the "unverified_lazy" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasUnverifiedLazy {
      get { return (_hasBits0 & 64) != 0; }
    }
    /// <summary>Clears the value of the "unverified_lazy" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearUnverifiedLazy() {
      _hasBits0 &= ~64;
    }

    /// <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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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>
    /// DEPRECATED. DO NOT USE!
    /// For Google-internal migration only. Do not use.
    /// </summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasWeak {
      get { return (_hasBits0 & 32) != 0; }
    }
    /// <summary>Clears the value of the "weak" field</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearWeak() {
      _hasBits0 &= ~32;
    }

    /// <summary>Field number for the "debug_redact" field.</summary>
    public const int DebugRedactFieldNumber = 16;
    private readonly static bool DebugRedactDefaultValue = false;

    private bool debugRedact_;
    /// <summary>
    /// Indicate that the field value should not be printed out when using debug
    /// formats, e.g. when the field contains sensitive credentials.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool DebugRedact {
      get { if ((_hasBits0 & 128) != 0) { return debugRedact_; } else { return DebugRedactDefaultValue; } }
      set {
        _hasBits0 |= 128;
        debugRedact_ = value;
      }
    }
    /// <summary>Gets whether the "debug_redact" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDebugRedact {
      get { return (_hasBits0 & 128) != 0; }
    }
    /// <summary>Clears the value of the "debug_redact" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDebugRedact() {
      _hasBits0 &= ~128;
    }

    /// <summary>Field number for the "retention" field.</summary>
    public const int RetentionFieldNumber = 17;
    private readonly static global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention RetentionDefaultValue = global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention.RetentionUnknown;

    private global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention retention_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention Retention {
      get { if ((_hasBits0 & 256) != 0) { return retention_; } else { return RetentionDefaultValue; } }
      set {
        _hasBits0 |= 256;
        retention_ = value;
      }
    }
    /// <summary>Gets whether the "retention" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasRetention {
      get { return (_hasBits0 & 256) != 0; }
    }
    /// <summary>Clears the value of the "retention" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearRetention() {
      _hasBits0 &= ~256;
    }

    /// <summary>Field number for the "targets" field.</summary>
    public const int TargetsFieldNumber = 19;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType> _repeated_targets_codec
        = pb::FieldCodec.ForEnum(152, x => (int) x, x => (global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType) x);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType> targets_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldOptions.Types.OptionTargetType> Targets {
      get { return targets_; }
    }

    /// <summary>Field number for the "edition_defaults" field.</summary>
    public const int EditionDefaultsFieldNumber = 20;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault> _repeated_editionDefaults_codec
        = pb::FieldCodec.ForMessage(162, global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault> editionDefaults_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FieldOptions.Types.EditionDefault> EditionDefaults {
      get { return editionDefaults_; }
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 21;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

    /// <summary>Field number for the "feature_support" field.</summary>
    public const int FeatureSupportFieldNumber = 22;
    private global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport featureSupport_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport FeatureSupport {
      get { return featureSupport_; }
      set {
        featureSupport_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FieldOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (UnverifiedLazy != other.UnverifiedLazy) return false;
      if (Deprecated != other.Deprecated) return false;
      if (Weak != other.Weak) return false;
      if (DebugRedact != other.DebugRedact) return false;
      if (Retention != other.Retention) return false;
      if(!targets_.Equals(other.targets_)) return false;
      if(!editionDefaults_.Equals(other.editionDefaults_)) return false;
      if (!object.Equals(Features, other.Features)) return false;
      if (!object.Equals(FeatureSupport, other.FeatureSupport)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (HasUnverifiedLazy) hash ^= UnverifiedLazy.GetHashCode();
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasWeak) hash ^= Weak.GetHashCode();
      if (HasDebugRedact) hash ^= DebugRedact.GetHashCode();
      if (HasRetention) hash ^= Retention.GetHashCode();
      hash ^= targets_.GetHashCode();
      hash ^= editionDefaults_.GetHashCode();
      if (features_ != null) hash ^= Features.GetHashCode();
      if (featureSupport_ != null) hash ^= FeatureSupport.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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);
      }
      if (HasUnverifiedLazy) {
        output.WriteRawTag(120);
        output.WriteBool(UnverifiedLazy);
      }
      if (HasDebugRedact) {
        output.WriteRawTag(128, 1);
        output.WriteBool(DebugRedact);
      }
      if (HasRetention) {
        output.WriteRawTag(136, 1);
        output.WriteEnum((int) Retention);
      }
      targets_.WriteTo(output, _repeated_targets_codec);
      editionDefaults_.WriteTo(output, _repeated_editionDefaults_codec);
      if (features_ != null) {
        output.WriteRawTag(170, 1);
        output.WriteMessage(Features);
      }
      if (featureSupport_ != null) {
        output.WriteRawTag(178, 1);
        output.WriteMessage(FeatureSupport);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext 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);
      }
      if (HasUnverifiedLazy) {
        output.WriteRawTag(120);
        output.WriteBool(UnverifiedLazy);
      }
      if (HasDebugRedact) {
        output.WriteRawTag(128, 1);
        output.WriteBool(DebugRedact);
      }
      if (HasRetention) {
        output.WriteRawTag(136, 1);
        output.WriteEnum((int) Retention);
      }
      targets_.WriteTo(ref output, _repeated_targets_codec);
      editionDefaults_.WriteTo(ref output, _repeated_editionDefaults_codec);
      if (features_ != null) {
        output.WriteRawTag(170, 1);
        output.WriteMessage(Features);
      }
      if (featureSupport_ != null) {
        output.WriteRawTag(178, 1);
        output.WriteMessage(FeatureSupport);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (HasUnverifiedLazy) {
        size += 1 + 1;
      }
      if (HasDeprecated) {
        size += 1 + 1;
      }
      if (HasWeak) {
        size += 1 + 1;
      }
      if (HasDebugRedact) {
        size += 2 + 1;
      }
      if (HasRetention) {
        size += 2 + pb::CodedOutputStream.ComputeEnumSize((int) Retention);
      }
      size += targets_.CalculateSize(_repeated_targets_codec);
      size += editionDefaults_.CalculateSize(_repeated_editionDefaults_codec);
      if (features_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      if (featureSupport_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(FeatureSupport);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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.HasUnverifiedLazy) {
        UnverifiedLazy = other.UnverifiedLazy;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasWeak) {
        Weak = other.Weak;
      }
      if (other.HasDebugRedact) {
        DebugRedact = other.DebugRedact;
      }
      if (other.HasRetention) {
        Retention = other.Retention;
      }
      targets_.Add(other.targets_);
      editionDefaults_.Add(other.editionDefaults_);
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      if (other.featureSupport_ != null) {
        if (featureSupport_ == null) {
          FeatureSupport = new global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport();
        }
        FeatureSupport.MergeFrom(other.FeatureSupport);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      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 120: {
            UnverifiedLazy = input.ReadBool();
            break;
          }
          case 128: {
            DebugRedact = input.ReadBool();
            break;
          }
          case 136: {
            Retention = (global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention) input.ReadEnum();
            break;
          }
          case 154:
          case 152: {
            targets_.AddEntriesFrom(input, _repeated_targets_codec);
            break;
          }
          case 162: {
            editionDefaults_.AddEntriesFrom(input, _repeated_editionDefaults_codec);
            break;
          }
          case 170: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 178: {
            if (featureSupport_ == null) {
              FeatureSupport = new global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport();
            }
            input.ReadMessage(FeatureSupport);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref 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 120: {
            UnverifiedLazy = input.ReadBool();
            break;
          }
          case 128: {
            DebugRedact = input.ReadBool();
            break;
          }
          case 136: {
            Retention = (global::Google.Protobuf.Reflection.FieldOptions.Types.OptionRetention) input.ReadEnum();
            break;
          }
          case 154:
          case 152: {
            targets_.AddEntriesFrom(ref input, _repeated_targets_codec);
            break;
          }
          case 162: {
            editionDefaults_.AddEntriesFrom(ref input, _repeated_editionDefaults_codec);
            break;
          }
          case 170: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 178: {
            if (featureSupport_ == null) {
              FeatureSupport = new global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport();
            }
            input.ReadMessage(FeatureSupport);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      public enum CType {
        /// <summary>
        /// Default mode.
        /// </summary>
        [pbr::OriginalName("STRING")] String = 0,
        /// <summary>
        /// The option [ctype=CORD] may be applied to a non-repeated field of type
        /// "bytes". It indicates that in C++, the data should be stored in a Cord
        /// instead of a string.  For very large strings, this may reduce memory
        /// fragmentation. It may also allow better performance when parsing from a
        /// Cord, or when parsing with aliasing enabled, as the parsed Cord may then
        /// alias the original buffer.
        /// </summary>
        [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,
      }

      /// <summary>
      /// If set to RETENTION_SOURCE, the option will be omitted from the binary.
      /// </summary>
      public enum OptionRetention {
        [pbr::OriginalName("RETENTION_UNKNOWN")] RetentionUnknown = 0,
        [pbr::OriginalName("RETENTION_RUNTIME")] RetentionRuntime = 1,
        [pbr::OriginalName("RETENTION_SOURCE")] RetentionSource = 2,
      }

      /// <summary>
      /// This indicates the types of entities that the field may apply to when used
      /// as an option. If it is unset, then the field may be freely used as an
      /// option on any kind of entity.
      /// </summary>
      public enum OptionTargetType {
        [pbr::OriginalName("TARGET_TYPE_UNKNOWN")] TargetTypeUnknown = 0,
        [pbr::OriginalName("TARGET_TYPE_FILE")] TargetTypeFile = 1,
        [pbr::OriginalName("TARGET_TYPE_EXTENSION_RANGE")] TargetTypeExtensionRange = 2,
        [pbr::OriginalName("TARGET_TYPE_MESSAGE")] TargetTypeMessage = 3,
        [pbr::OriginalName("TARGET_TYPE_FIELD")] TargetTypeField = 4,
        [pbr::OriginalName("TARGET_TYPE_ONEOF")] TargetTypeOneof = 5,
        [pbr::OriginalName("TARGET_TYPE_ENUM")] TargetTypeEnum = 6,
        [pbr::OriginalName("TARGET_TYPE_ENUM_ENTRY")] TargetTypeEnumEntry = 7,
        [pbr::OriginalName("TARGET_TYPE_SERVICE")] TargetTypeService = 8,
        [pbr::OriginalName("TARGET_TYPE_METHOD")] TargetTypeMethod = 9,
      }

      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class EditionDefault : pb::IMessage<EditionDefault>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<EditionDefault> _parser = new pb::MessageParser<EditionDefault>(() => new EditionDefault());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<EditionDefault> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.FieldOptions.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public EditionDefault() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public EditionDefault(EditionDefault other) : this() {
          _hasBits0 = other._hasBits0;
          edition_ = other.edition_;
          value_ = other.value_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public EditionDefault Clone() {
          return new EditionDefault(this);
        }

        /// <summary>Field number for the "edition" field.</summary>
        public const int EditionFieldNumber = 3;
        private readonly static global::Google.Protobuf.Reflection.Edition EditionDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

        private global::Google.Protobuf.Reflection.Edition edition_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.Edition Edition {
          get { if ((_hasBits0 & 1) != 0) { return edition_; } else { return EditionDefaultValue; } }
          set {
            _hasBits0 |= 1;
            edition_ = value;
          }
        }
        /// <summary>Gets whether the "edition" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEdition {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "edition" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEdition() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "value" field.</summary>
        public const int ValueFieldNumber = 2;
        private readonly static string ValueDefaultValue = "";

        private string value_;
        /// <summary>
        /// Textproto value.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public string Value {
          get { return value_ ?? ValueDefaultValue; }
          set {
            value_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "value" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasValue {
          get { return value_ != null; }
        }
        /// <summary>Clears the value of the "value" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearValue() {
          value_ = null;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as EditionDefault);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Equals(EditionDefault other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Edition != other.Edition) return false;
          if (Value != other.Value) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override int GetHashCode() {
          int hash = 1;
          if (HasEdition) hash ^= Edition.GetHashCode();
          if (HasValue) hash ^= Value.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasValue) {
            output.WriteRawTag(18);
            output.WriteString(Value);
          }
          if (HasEdition) {
            output.WriteRawTag(24);
            output.WriteEnum((int) Edition);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasValue) {
            output.WriteRawTag(18);
            output.WriteString(Value);
          }
          if (HasEdition) {
            output.WriteRawTag(24);
            output.WriteEnum((int) Edition);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public int CalculateSize() {
          int size = 0;
          if (HasEdition) {
            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Edition);
          }
          if (HasValue) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(Value);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(EditionDefault other) {
          if (other == null) {
            return;
          }
          if (other.HasEdition) {
            Edition = other.Edition;
          }
          if (other.HasValue) {
            Value = other.Value;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 18: {
                Value = input.ReadString();
                break;
              }
              case 24: {
                Edition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 18: {
                Value = input.ReadString();
                break;
              }
              case 24: {
                Edition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
            }
          }
        }
        #endif

      }

      /// <summary>
      /// Information about the support window of a feature.
      /// </summary>
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class FeatureSupport : pb::IMessage<FeatureSupport>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<FeatureSupport> _parser = new pb::MessageParser<FeatureSupport>(() => new FeatureSupport());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<FeatureSupport> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.FieldOptions.Descriptor.NestedTypes[1]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public FeatureSupport() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public FeatureSupport(FeatureSupport other) : this() {
          _hasBits0 = other._hasBits0;
          editionIntroduced_ = other.editionIntroduced_;
          editionDeprecated_ = other.editionDeprecated_;
          deprecationWarning_ = other.deprecationWarning_;
          editionRemoved_ = other.editionRemoved_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public FeatureSupport Clone() {
          return new FeatureSupport(this);
        }

        /// <summary>Field number for the "edition_introduced" field.</summary>
        public const int EditionIntroducedFieldNumber = 1;
        private readonly static global::Google.Protobuf.Reflection.Edition EditionIntroducedDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

        private global::Google.Protobuf.Reflection.Edition editionIntroduced_;
        /// <summary>
        /// The edition that this feature was first available in.  In editions
        /// earlier than this one, the default assigned to EDITION_LEGACY will be
        /// used, and proto files will not be able to override it.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.Edition EditionIntroduced {
          get { if ((_hasBits0 & 1) != 0) { return editionIntroduced_; } else { return EditionIntroducedDefaultValue; } }
          set {
            _hasBits0 |= 1;
            editionIntroduced_ = value;
          }
        }
        /// <summary>Gets whether the "edition_introduced" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEditionIntroduced {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "edition_introduced" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEditionIntroduced() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "edition_deprecated" field.</summary>
        public const int EditionDeprecatedFieldNumber = 2;
        private readonly static global::Google.Protobuf.Reflection.Edition EditionDeprecatedDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

        private global::Google.Protobuf.Reflection.Edition editionDeprecated_;
        /// <summary>
        /// The edition this feature becomes deprecated in.  Using this after this
        /// edition may trigger warnings.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.Edition EditionDeprecated {
          get { if ((_hasBits0 & 2) != 0) { return editionDeprecated_; } else { return EditionDeprecatedDefaultValue; } }
          set {
            _hasBits0 |= 2;
            editionDeprecated_ = value;
          }
        }
        /// <summary>Gets whether the "edition_deprecated" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEditionDeprecated {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "edition_deprecated" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEditionDeprecated() {
          _hasBits0 &= ~2;
        }

        /// <summary>Field number for the "deprecation_warning" field.</summary>
        public const int DeprecationWarningFieldNumber = 3;
        private readonly static string DeprecationWarningDefaultValue = "";

        private string deprecationWarning_;
        /// <summary>
        /// The deprecation warning text if this feature is used after the edition it
        /// was marked deprecated in.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public string DeprecationWarning {
          get { return deprecationWarning_ ?? DeprecationWarningDefaultValue; }
          set {
            deprecationWarning_ = pb::ProtoPreconditions.CheckNotNull(value, "value");
          }
        }
        /// <summary>Gets whether the "deprecation_warning" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasDeprecationWarning {
          get { return deprecationWarning_ != null; }
        }
        /// <summary>Clears the value of the "deprecation_warning" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearDeprecationWarning() {
          deprecationWarning_ = null;
        }

        /// <summary>Field number for the "edition_removed" field.</summary>
        public const int EditionRemovedFieldNumber = 4;
        private readonly static global::Google.Protobuf.Reflection.Edition EditionRemovedDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

        private global::Google.Protobuf.Reflection.Edition editionRemoved_;
        /// <summary>
        /// The edition this feature is no longer available in.  In editions after
        /// this one, the last default assigned will be used, and proto files will
        /// not be able to override it.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.Edition EditionRemoved {
          get { if ((_hasBits0 & 4) != 0) { return editionRemoved_; } else { return EditionRemovedDefaultValue; } }
          set {
            _hasBits0 |= 4;
            editionRemoved_ = value;
          }
        }
        /// <summary>Gets whether the "edition_removed" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEditionRemoved {
          get { return (_hasBits0 & 4) != 0; }
        }
        /// <summary>Clears the value of the "edition_removed" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEditionRemoved() {
          _hasBits0 &= ~4;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as FeatureSupport);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Equals(FeatureSupport other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (EditionIntroduced != other.EditionIntroduced) return false;
          if (EditionDeprecated != other.EditionDeprecated) return false;
          if (DeprecationWarning != other.DeprecationWarning) return false;
          if (EditionRemoved != other.EditionRemoved) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override int GetHashCode() {
          int hash = 1;
          if (HasEditionIntroduced) hash ^= EditionIntroduced.GetHashCode();
          if (HasEditionDeprecated) hash ^= EditionDeprecated.GetHashCode();
          if (HasDeprecationWarning) hash ^= DeprecationWarning.GetHashCode();
          if (HasEditionRemoved) hash ^= EditionRemoved.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasEditionIntroduced) {
            output.WriteRawTag(8);
            output.WriteEnum((int) EditionIntroduced);
          }
          if (HasEditionDeprecated) {
            output.WriteRawTag(16);
            output.WriteEnum((int) EditionDeprecated);
          }
          if (HasDeprecationWarning) {
            output.WriteRawTag(26);
            output.WriteString(DeprecationWarning);
          }
          if (HasEditionRemoved) {
            output.WriteRawTag(32);
            output.WriteEnum((int) EditionRemoved);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasEditionIntroduced) {
            output.WriteRawTag(8);
            output.WriteEnum((int) EditionIntroduced);
          }
          if (HasEditionDeprecated) {
            output.WriteRawTag(16);
            output.WriteEnum((int) EditionDeprecated);
          }
          if (HasDeprecationWarning) {
            output.WriteRawTag(26);
            output.WriteString(DeprecationWarning);
          }
          if (HasEditionRemoved) {
            output.WriteRawTag(32);
            output.WriteEnum((int) EditionRemoved);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public int CalculateSize() {
          int size = 0;
          if (HasEditionIntroduced) {
            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EditionIntroduced);
          }
          if (HasEditionDeprecated) {
            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EditionDeprecated);
          }
          if (HasDeprecationWarning) {
            size += 1 + pb::CodedOutputStream.ComputeStringSize(DeprecationWarning);
          }
          if (HasEditionRemoved) {
            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EditionRemoved);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(FeatureSupport other) {
          if (other == null) {
            return;
          }
          if (other.HasEditionIntroduced) {
            EditionIntroduced = other.EditionIntroduced;
          }
          if (other.HasEditionDeprecated) {
            EditionDeprecated = other.EditionDeprecated;
          }
          if (other.HasDeprecationWarning) {
            DeprecationWarning = other.DeprecationWarning;
          }
          if (other.HasEditionRemoved) {
            EditionRemoved = other.EditionRemoved;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 8: {
                EditionIntroduced = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
              case 16: {
                EditionDeprecated = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
              case 26: {
                DeprecationWarning = input.ReadString();
                break;
              }
              case 32: {
                EditionRemoved = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 8: {
                EditionIntroduced = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
              case 16: {
                EditionDeprecated = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
              case 26: {
                DeprecationWarning = input.ReadString();
                break;
              }
              case 32: {
                EditionRemoved = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class OneofOptions : pb::IExtendableMessage<OneofOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<OneofOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[13]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public OneofOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public OneofOptions(OneofOptions other) : this() {
      features_ = other.features_ != null ? other.features_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public OneofOptions Clone() {
      return new OneofOptions(this);
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 1;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as OneofOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(OneofOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(Features, other.Features)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (features_ != null) hash ^= Features.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (features_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (features_ != null) {
        output.WriteRawTag(10);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (features_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(OneofOptions other) {
      if (other == null) {
        return;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 10: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 10: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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);
    }

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class EnumOptions : pb::IExtendableMessage<EnumOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<EnumOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[14]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumOptions(EnumOptions other) : this() {
      _hasBits0 = other._hasBits0;
      allowAlias_ = other.allowAlias_;
      deprecated_ = other.deprecated_;
      deprecatedLegacyJsonFieldConflicts_ = other.deprecatedLegacyJsonFieldConflicts_;
      features_ = other.features_ != null ? other.features_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasAllowAlias {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "allow_alias" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDeprecated() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "deprecated_legacy_json_field_conflicts" field.</summary>
    public const int DeprecatedLegacyJsonFieldConflictsFieldNumber = 6;
    private readonly static bool DeprecatedLegacyJsonFieldConflictsDefaultValue = false;

    private bool deprecatedLegacyJsonFieldConflicts_;
    /// <summary>
    /// Enable the legacy handling of JSON field name conflicts.  This lowercases
    /// and strips underscored from the fields before comparison in proto3 only.
    /// The new behavior takes `json_name` into account and applies to proto2 as
    /// well.
    /// TODO Remove this legacy behavior once downstream teams have
    /// had time to migrate.
    /// </summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool DeprecatedLegacyJsonFieldConflicts {
      get { if ((_hasBits0 & 4) != 0) { return deprecatedLegacyJsonFieldConflicts_; } else { return DeprecatedLegacyJsonFieldConflictsDefaultValue; } }
      set {
        _hasBits0 |= 4;
        deprecatedLegacyJsonFieldConflicts_ = value;
      }
    }
    /// <summary>Gets whether the "deprecated_legacy_json_field_conflicts" field is set</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecatedLegacyJsonFieldConflicts {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "deprecated_legacy_json_field_conflicts" field</summary>
    [global::System.ObsoleteAttribute]
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDeprecatedLegacyJsonFieldConflicts() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 7;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as EnumOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (DeprecatedLegacyJsonFieldConflicts != other.DeprecatedLegacyJsonFieldConflicts) return false;
      if (!object.Equals(Features, other.Features)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasAllowAlias) hash ^= AllowAlias.GetHashCode();
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasDeprecatedLegacyJsonFieldConflicts) hash ^= DeprecatedLegacyJsonFieldConflicts.GetHashCode();
      if (features_ != null) hash ^= Features.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasAllowAlias) {
        output.WriteRawTag(16);
        output.WriteBool(AllowAlias);
      }
      if (HasDeprecated) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      if (HasDeprecatedLegacyJsonFieldConflicts) {
        output.WriteRawTag(48);
        output.WriteBool(DeprecatedLegacyJsonFieldConflicts);
      }
      if (features_ != null) {
        output.WriteRawTag(58);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasAllowAlias) {
        output.WriteRawTag(16);
        output.WriteBool(AllowAlias);
      }
      if (HasDeprecated) {
        output.WriteRawTag(24);
        output.WriteBool(Deprecated);
      }
      if (HasDeprecatedLegacyJsonFieldConflicts) {
        output.WriteRawTag(48);
        output.WriteBool(DeprecatedLegacyJsonFieldConflicts);
      }
      if (features_ != null) {
        output.WriteRawTag(58);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasAllowAlias) {
        size += 1 + 1;
      }
      if (HasDeprecated) {
        size += 1 + 1;
      }
      if (HasDeprecatedLegacyJsonFieldConflicts) {
        size += 1 + 1;
      }
      if (features_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(EnumOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasAllowAlias) {
        AllowAlias = other.AllowAlias;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasDeprecatedLegacyJsonFieldConflicts) {
        DeprecatedLegacyJsonFieldConflicts = other.DeprecatedLegacyJsonFieldConflicts;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      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 48: {
            DeprecatedLegacyJsonFieldConflicts = input.ReadBool();
            break;
          }
          case 58: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 16: {
            AllowAlias = input.ReadBool();
            break;
          }
          case 24: {
            Deprecated = input.ReadBool();
            break;
          }
          case 48: {
            DeprecatedLegacyJsonFieldConflicts = input.ReadBool();
            break;
          }
          case 58: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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);
    }

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class EnumValueOptions : pb::IExtendableMessage<EnumValueOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<EnumValueOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[15]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumValueOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public EnumValueOptions(EnumValueOptions other) : this() {
      _hasBits0 = other._hasBits0;
      deprecated_ = other.deprecated_;
      features_ = other.features_ != null ? other.features_.Clone() : null;
      debugRedact_ = other.debugRedact_;
      featureSupport_ = other.featureSupport_ != null ? other.featureSupport_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDeprecated() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 2;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

    /// <summary>Field number for the "debug_redact" field.</summary>
    public const int DebugRedactFieldNumber = 3;
    private readonly static bool DebugRedactDefaultValue = false;

    private bool debugRedact_;
    /// <summary>
    /// Indicate that fields annotated with this enum value should not be printed
    /// out when using debug formats, e.g. when the field contains sensitive
    /// credentials.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool DebugRedact {
      get { if ((_hasBits0 & 2) != 0) { return debugRedact_; } else { return DebugRedactDefaultValue; } }
      set {
        _hasBits0 |= 2;
        debugRedact_ = value;
      }
    }
    /// <summary>Gets whether the "debug_redact" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDebugRedact {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "debug_redact" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDebugRedact() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "feature_support" field.</summary>
    public const int FeatureSupportFieldNumber = 4;
    private global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport featureSupport_;
    /// <summary>
    /// Information about the support window of a feature value.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport FeatureSupport {
      get { return featureSupport_; }
      set {
        featureSupport_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as EnumValueOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(EnumValueOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (Deprecated != other.Deprecated) return false;
      if (!object.Equals(Features, other.Features)) return false;
      if (DebugRedact != other.DebugRedact) return false;
      if (!object.Equals(FeatureSupport, other.FeatureSupport)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (features_ != null) hash ^= Features.GetHashCode();
      if (HasDebugRedact) hash ^= DebugRedact.GetHashCode();
      if (featureSupport_ != null) hash ^= FeatureSupport.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasDeprecated) {
        output.WriteRawTag(8);
        output.WriteBool(Deprecated);
      }
      if (features_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(Features);
      }
      if (HasDebugRedact) {
        output.WriteRawTag(24);
        output.WriteBool(DebugRedact);
      }
      if (featureSupport_ != null) {
        output.WriteRawTag(34);
        output.WriteMessage(FeatureSupport);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasDeprecated) {
        output.WriteRawTag(8);
        output.WriteBool(Deprecated);
      }
      if (features_ != null) {
        output.WriteRawTag(18);
        output.WriteMessage(Features);
      }
      if (HasDebugRedact) {
        output.WriteRawTag(24);
        output.WriteBool(DebugRedact);
      }
      if (featureSupport_ != null) {
        output.WriteRawTag(34);
        output.WriteMessage(FeatureSupport);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasDeprecated) {
        size += 1 + 1;
      }
      if (features_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      if (HasDebugRedact) {
        size += 1 + 1;
      }
      if (featureSupport_ != null) {
        size += 1 + pb::CodedOutputStream.ComputeMessageSize(FeatureSupport);
      }
      size += uninterpretedOption_.CalculateSize(_repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(EnumValueOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      if (other.HasDebugRedact) {
        DebugRedact = other.DebugRedact;
      }
      if (other.featureSupport_ != null) {
        if (featureSupport_ == null) {
          FeatureSupport = new global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport();
        }
        FeatureSupport.MergeFrom(other.FeatureSupport);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 8: {
            Deprecated = input.ReadBool();
            break;
          }
          case 18: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 24: {
            DebugRedact = input.ReadBool();
            break;
          }
          case 34: {
            if (featureSupport_ == null) {
              FeatureSupport = new global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport();
            }
            input.ReadMessage(FeatureSupport);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 8: {
            Deprecated = input.ReadBool();
            break;
          }
          case 18: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 24: {
            DebugRedact = input.ReadBool();
            break;
          }
          case 34: {
            if (featureSupport_ == null) {
              FeatureSupport = new global::Google.Protobuf.Reflection.FieldOptions.Types.FeatureSupport();
            }
            input.ReadMessage(FeatureSupport);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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);
    }

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class ServiceOptions : pb::IExtendableMessage<ServiceOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<ServiceOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[16]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ServiceOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ServiceOptions(ServiceOptions other) : this() {
      _hasBits0 = other._hasBits0;
      features_ = other.features_ != null ? other.features_.Clone() : null;
      deprecated_ = other.deprecated_;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public ServiceOptions Clone() {
      return new ServiceOptions(this);
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 34;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

    /// <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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.UninterpretedOption> UninterpretedOption {
      get { return uninterpretedOption_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as ServiceOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(ServiceOptions other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (!object.Equals(Features, other.Features)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (features_ != null) hash ^= Features.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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasDeprecated) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      if (features_ != null) {
        output.WriteRawTag(146, 2);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasDeprecated) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      if (features_ != null) {
        output.WriteRawTag(146, 2);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (features_ != null) {
        size += 2 + pb::CodedOutputStream.ComputeMessageSize(Features);
      }
      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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(ServiceOptions other) {
      if (other == null) {
        return;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 264: {
            Deprecated = input.ReadBool();
            break;
          }
          case 274: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 264: {
            Deprecated = input.ReadBool();
            break;
          }
          case 274: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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);
    }

  }

  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class MethodOptions : pb::IExtendableMessage<MethodOptions>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    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 { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<MethodOptions> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[17]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public MethodOptions() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public MethodOptions(MethodOptions other) : this() {
      _hasBits0 = other._hasBits0;
      deprecated_ = other.deprecated_;
      idempotencyLevel_ = other.idempotencyLevel_;
      features_ = other.features_ != null ? other.features_.Clone() : null;
      uninterpretedOption_ = other.uninterpretedOption_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDeprecated {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "deprecated" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasIdempotencyLevel {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "idempotency_level" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearIdempotencyLevel() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "features" field.</summary>
    public const int FeaturesFieldNumber = 35;
    private global::Google.Protobuf.Reflection.FeatureSet features_;
    /// <summary>
    /// Any features defined in the specific edition.
    /// WARNING: This field should only be used by protobuf plugins or special
    /// cases like the proto compiler. Other uses are discouraged and
    /// developers should rely on the protoreflect APIs for their client language.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet Features {
      get { return features_; }
      set {
        features_ = value;
      }
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as MethodOptions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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 (!object.Equals(Features, other.Features)) 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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasDeprecated) hash ^= Deprecated.GetHashCode();
      if (HasIdempotencyLevel) hash ^= IdempotencyLevel.GetHashCode();
      if (features_ != null) hash ^= Features.GetHashCode();
      hash ^= uninterpretedOption_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasDeprecated) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      if (HasIdempotencyLevel) {
        output.WriteRawTag(144, 2);
        output.WriteEnum((int) IdempotencyLevel);
      }
      if (features_ != null) {
        output.WriteRawTag(154, 2);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasDeprecated) {
        output.WriteRawTag(136, 2);
        output.WriteBool(Deprecated);
      }
      if (HasIdempotencyLevel) {
        output.WriteRawTag(144, 2);
        output.WriteEnum((int) IdempotencyLevel);
      }
      if (features_ != null) {
        output.WriteRawTag(154, 2);
        output.WriteMessage(Features);
      }
      uninterpretedOption_.WriteTo(ref output, _repeated_uninterpretedOption_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(MethodOptions other) {
      if (other == null) {
        return;
      }
      if (other.HasDeprecated) {
        Deprecated = other.Deprecated;
      }
      if (other.HasIdempotencyLevel) {
        IdempotencyLevel = other.IdempotencyLevel;
      }
      if (other.features_ != null) {
        if (features_ == null) {
          Features = new global::Google.Protobuf.Reflection.FeatureSet();
        }
        Features.MergeFrom(other.Features);
      }
      uninterpretedOption_.Add(other.uninterpretedOption_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      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 282: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 264: {
            Deprecated = input.ReadBool();
            break;
          }
          case 272: {
            IdempotencyLevel = (global::Google.Protobuf.Reflection.MethodOptions.Types.IdempotencyLevel) input.ReadEnum();
            break;
          }
          case 282: {
            if (features_ == null) {
              Features = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            input.ReadMessage(Features);
            break;
          }
          case 7994: {
            uninterpretedOption_.AddEntriesFrom(ref input, _repeated_uninterpretedOption_codec);
            break;
          }
        }
      }
    }
    #endif

    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class UninterpretedOption : pb::IMessage<UninterpretedOption>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<UninterpretedOption> _parser = new pb::MessageParser<UninterpretedOption>(() => new UninterpretedOption());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<UninterpretedOption> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[18]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public UninterpretedOption() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasIdentifierValue {
      get { return identifierValue_ != null; }
    }
    /// <summary>Clears the value of the "identifier_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasPositiveIntValue {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "positive_int_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasNegativeIntValue {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "negative_int_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDoubleValue {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "double_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasStringValue {
      get { return stringValue_ != null; }
    }
    /// <summary>Clears the value of the "string_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasAggregateValue {
      get { return aggregateValue_ != null; }
    }
    /// <summary>Clears the value of the "aggregate_value" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearAggregateValue() {
      aggregateValue_ = null;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as UninterpretedOption);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      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);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      name_.WriteTo(ref 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(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      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;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 18: {
            name_.AddEntriesFrom(ref 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;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the UninterpretedOption message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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], ["moo", false] } represents
      /// "foo.(bar.baz).moo".
      /// </summary>
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class NamePart : pb::IMessage<NamePart>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<NamePart> _parser = new pb::MessageParser<NamePart>(() => new NamePart());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<NamePart> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.UninterpretedOption.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public NamePart() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public NamePart(NamePart other) : this() {
          _hasBits0 = other._hasBits0;
          namePart_ = other.namePart_;
          isExtension_ = other.isExtension_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasNamePart_ {
          get { return namePart_ != null; }
        }
        /// <summary>Clears the value of the "name_part" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasIsExtension {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "is_extension" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearIsExtension() {
          _hasBits0 &= ~1;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as NamePart);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasNamePart_) {
            output.WriteRawTag(10);
            output.WriteString(NamePart_);
          }
          if (HasIsExtension) {
            output.WriteRawTag(16);
            output.WriteBool(IsExtension);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasNamePart_) {
            output.WriteRawTag(10);
            output.WriteString(NamePart_);
          }
          if (HasIsExtension) {
            output.WriteRawTag(16);
            output.WriteBool(IsExtension);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 10: {
                NamePart_ = input.ReadString();
                break;
              }
              case 16: {
                IsExtension = input.ReadBool();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 10: {
                NamePart_ = input.ReadString();
                break;
              }
              case 16: {
                IsExtension = input.ReadBool();
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  /// <summary>
  /// TODO Enums in C++ gencode (and potentially other languages) are
  /// not well scoped.  This means that each of the feature enums below can clash
  /// with each other.  The short names we've chosen maximize call-site
  /// readability, but leave us very open to this scenario.  A future feature will
  /// be designed and implemented to handle this, hopefully before we ever hit a
  /// conflict here.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FeatureSet : pb::IExtendableMessage<FeatureSet>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<FeatureSet> _parser = new pb::MessageParser<FeatureSet>(() => new FeatureSet());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<FeatureSet> _extensions;
    private pb::ExtensionSet<FeatureSet> _Extensions { get { return _extensions; } }
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FeatureSet> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[19]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FeatureSet() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FeatureSet(FeatureSet other) : this() {
      _hasBits0 = other._hasBits0;
      fieldPresence_ = other.fieldPresence_;
      enumType_ = other.enumType_;
      repeatedFieldEncoding_ = other.repeatedFieldEncoding_;
      utf8Validation_ = other.utf8Validation_;
      messageEncoding_ = other.messageEncoding_;
      jsonFormat_ = other.jsonFormat_;
      enforceNamingStyle_ = other.enforceNamingStyle_;
      defaultSymbolVisibility_ = other.defaultSymbolVisibility_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FeatureSet Clone() {
      return new FeatureSet(this);
    }

    /// <summary>Field number for the "field_presence" field.</summary>
    public const int FieldPresenceFieldNumber = 1;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence FieldPresenceDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence fieldPresence_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence FieldPresence {
      get { if ((_hasBits0 & 1) != 0) { return fieldPresence_; } else { return FieldPresenceDefaultValue; } }
      set {
        _hasBits0 |= 1;
        fieldPresence_ = value;
      }
    }
    /// <summary>Gets whether the "field_presence" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasFieldPresence {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "field_presence" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearFieldPresence() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "enum_type" field.</summary>
    public const int EnumTypeFieldNumber = 2;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType EnumTypeDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType enumType_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType EnumType {
      get { if ((_hasBits0 & 2) != 0) { return enumType_; } else { return EnumTypeDefaultValue; } }
      set {
        _hasBits0 |= 2;
        enumType_ = value;
      }
    }
    /// <summary>Gets whether the "enum_type" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasEnumType {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "enum_type" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearEnumType() {
      _hasBits0 &= ~2;
    }

    /// <summary>Field number for the "repeated_field_encoding" field.</summary>
    public const int RepeatedFieldEncodingFieldNumber = 3;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding RepeatedFieldEncodingDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding repeatedFieldEncoding_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding RepeatedFieldEncoding {
      get { if ((_hasBits0 & 4) != 0) { return repeatedFieldEncoding_; } else { return RepeatedFieldEncodingDefaultValue; } }
      set {
        _hasBits0 |= 4;
        repeatedFieldEncoding_ = value;
      }
    }
    /// <summary>Gets whether the "repeated_field_encoding" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasRepeatedFieldEncoding {
      get { return (_hasBits0 & 4) != 0; }
    }
    /// <summary>Clears the value of the "repeated_field_encoding" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearRepeatedFieldEncoding() {
      _hasBits0 &= ~4;
    }

    /// <summary>Field number for the "utf8_validation" field.</summary>
    public const int Utf8ValidationFieldNumber = 4;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation Utf8ValidationDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation utf8Validation_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation Utf8Validation {
      get { if ((_hasBits0 & 8) != 0) { return utf8Validation_; } else { return Utf8ValidationDefaultValue; } }
      set {
        _hasBits0 |= 8;
        utf8Validation_ = value;
      }
    }
    /// <summary>Gets whether the "utf8_validation" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasUtf8Validation {
      get { return (_hasBits0 & 8) != 0; }
    }
    /// <summary>Clears the value of the "utf8_validation" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearUtf8Validation() {
      _hasBits0 &= ~8;
    }

    /// <summary>Field number for the "message_encoding" field.</summary>
    public const int MessageEncodingFieldNumber = 5;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding MessageEncodingDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding messageEncoding_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding MessageEncoding {
      get { if ((_hasBits0 & 16) != 0) { return messageEncoding_; } else { return MessageEncodingDefaultValue; } }
      set {
        _hasBits0 |= 16;
        messageEncoding_ = value;
      }
    }
    /// <summary>Gets whether the "message_encoding" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasMessageEncoding {
      get { return (_hasBits0 & 16) != 0; }
    }
    /// <summary>Clears the value of the "message_encoding" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearMessageEncoding() {
      _hasBits0 &= ~16;
    }

    /// <summary>Field number for the "json_format" field.</summary>
    public const int JsonFormatFieldNumber = 6;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat JsonFormatDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat jsonFormat_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat JsonFormat {
      get { if ((_hasBits0 & 32) != 0) { return jsonFormat_; } else { return JsonFormatDefaultValue; } }
      set {
        _hasBits0 |= 32;
        jsonFormat_ = value;
      }
    }
    /// <summary>Gets whether the "json_format" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasJsonFormat {
      get { return (_hasBits0 & 32) != 0; }
    }
    /// <summary>Clears the value of the "json_format" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearJsonFormat() {
      _hasBits0 &= ~32;
    }

    /// <summary>Field number for the "enforce_naming_style" field.</summary>
    public const int EnforceNamingStyleFieldNumber = 7;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle EnforceNamingStyleDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle enforceNamingStyle_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle EnforceNamingStyle {
      get { if ((_hasBits0 & 64) != 0) { return enforceNamingStyle_; } else { return EnforceNamingStyleDefaultValue; } }
      set {
        _hasBits0 |= 64;
        enforceNamingStyle_ = value;
      }
    }
    /// <summary>Gets whether the "enforce_naming_style" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasEnforceNamingStyle {
      get { return (_hasBits0 & 64) != 0; }
    }
    /// <summary>Clears the value of the "enforce_naming_style" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearEnforceNamingStyle() {
      _hasBits0 &= ~64;
    }

    /// <summary>Field number for the "default_symbol_visibility" field.</summary>
    public const int DefaultSymbolVisibilityFieldNumber = 8;
    private readonly static global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility DefaultSymbolVisibilityDefaultValue = global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility.Unknown;

    private global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility defaultSymbolVisibility_;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility DefaultSymbolVisibility {
      get { if ((_hasBits0 & 128) != 0) { return defaultSymbolVisibility_; } else { return DefaultSymbolVisibilityDefaultValue; } }
      set {
        _hasBits0 |= 128;
        defaultSymbolVisibility_ = value;
      }
    }
    /// <summary>Gets whether the "default_symbol_visibility" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasDefaultSymbolVisibility {
      get { return (_hasBits0 & 128) != 0; }
    }
    /// <summary>Clears the value of the "default_symbol_visibility" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearDefaultSymbolVisibility() {
      _hasBits0 &= ~128;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FeatureSet);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(FeatureSet other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if (FieldPresence != other.FieldPresence) return false;
      if (EnumType != other.EnumType) return false;
      if (RepeatedFieldEncoding != other.RepeatedFieldEncoding) return false;
      if (Utf8Validation != other.Utf8Validation) return false;
      if (MessageEncoding != other.MessageEncoding) return false;
      if (JsonFormat != other.JsonFormat) return false;
      if (EnforceNamingStyle != other.EnforceNamingStyle) return false;
      if (DefaultSymbolVisibility != other.DefaultSymbolVisibility) return false;
      if (!Equals(_extensions, other._extensions)) {
        return false;
      }
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      if (HasFieldPresence) hash ^= FieldPresence.GetHashCode();
      if (HasEnumType) hash ^= EnumType.GetHashCode();
      if (HasRepeatedFieldEncoding) hash ^= RepeatedFieldEncoding.GetHashCode();
      if (HasUtf8Validation) hash ^= Utf8Validation.GetHashCode();
      if (HasMessageEncoding) hash ^= MessageEncoding.GetHashCode();
      if (HasJsonFormat) hash ^= JsonFormat.GetHashCode();
      if (HasEnforceNamingStyle) hash ^= EnforceNamingStyle.GetHashCode();
      if (HasDefaultSymbolVisibility) hash ^= DefaultSymbolVisibility.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      if (HasFieldPresence) {
        output.WriteRawTag(8);
        output.WriteEnum((int) FieldPresence);
      }
      if (HasEnumType) {
        output.WriteRawTag(16);
        output.WriteEnum((int) EnumType);
      }
      if (HasRepeatedFieldEncoding) {
        output.WriteRawTag(24);
        output.WriteEnum((int) RepeatedFieldEncoding);
      }
      if (HasUtf8Validation) {
        output.WriteRawTag(32);
        output.WriteEnum((int) Utf8Validation);
      }
      if (HasMessageEncoding) {
        output.WriteRawTag(40);
        output.WriteEnum((int) MessageEncoding);
      }
      if (HasJsonFormat) {
        output.WriteRawTag(48);
        output.WriteEnum((int) JsonFormat);
      }
      if (HasEnforceNamingStyle) {
        output.WriteRawTag(56);
        output.WriteEnum((int) EnforceNamingStyle);
      }
      if (HasDefaultSymbolVisibility) {
        output.WriteRawTag(64);
        output.WriteEnum((int) DefaultSymbolVisibility);
      }
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      if (HasFieldPresence) {
        output.WriteRawTag(8);
        output.WriteEnum((int) FieldPresence);
      }
      if (HasEnumType) {
        output.WriteRawTag(16);
        output.WriteEnum((int) EnumType);
      }
      if (HasRepeatedFieldEncoding) {
        output.WriteRawTag(24);
        output.WriteEnum((int) RepeatedFieldEncoding);
      }
      if (HasUtf8Validation) {
        output.WriteRawTag(32);
        output.WriteEnum((int) Utf8Validation);
      }
      if (HasMessageEncoding) {
        output.WriteRawTag(40);
        output.WriteEnum((int) MessageEncoding);
      }
      if (HasJsonFormat) {
        output.WriteRawTag(48);
        output.WriteEnum((int) JsonFormat);
      }
      if (HasEnforceNamingStyle) {
        output.WriteRawTag(56);
        output.WriteEnum((int) EnforceNamingStyle);
      }
      if (HasDefaultSymbolVisibility) {
        output.WriteRawTag(64);
        output.WriteEnum((int) DefaultSymbolVisibility);
      }
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      if (HasFieldPresence) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) FieldPresence);
      }
      if (HasEnumType) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnumType);
      }
      if (HasRepeatedFieldEncoding) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) RepeatedFieldEncoding);
      }
      if (HasUtf8Validation) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Utf8Validation);
      }
      if (HasMessageEncoding) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) MessageEncoding);
      }
      if (HasJsonFormat) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) JsonFormat);
      }
      if (HasEnforceNamingStyle) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) EnforceNamingStyle);
      }
      if (HasDefaultSymbolVisibility) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) DefaultSymbolVisibility);
      }
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(FeatureSet other) {
      if (other == null) {
        return;
      }
      if (other.HasFieldPresence) {
        FieldPresence = other.FieldPresence;
      }
      if (other.HasEnumType) {
        EnumType = other.EnumType;
      }
      if (other.HasRepeatedFieldEncoding) {
        RepeatedFieldEncoding = other.RepeatedFieldEncoding;
      }
      if (other.HasUtf8Validation) {
        Utf8Validation = other.Utf8Validation;
      }
      if (other.HasMessageEncoding) {
        MessageEncoding = other.MessageEncoding;
      }
      if (other.HasJsonFormat) {
        JsonFormat = other.JsonFormat;
      }
      if (other.HasEnforceNamingStyle) {
        EnforceNamingStyle = other.EnforceNamingStyle;
      }
      if (other.HasDefaultSymbolVisibility) {
        DefaultSymbolVisibility = other.DefaultSymbolVisibility;
      }
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 8: {
            FieldPresence = (global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence) input.ReadEnum();
            break;
          }
          case 16: {
            EnumType = (global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType) input.ReadEnum();
            break;
          }
          case 24: {
            RepeatedFieldEncoding = (global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding) input.ReadEnum();
            break;
          }
          case 32: {
            Utf8Validation = (global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation) input.ReadEnum();
            break;
          }
          case 40: {
            MessageEncoding = (global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding) input.ReadEnum();
            break;
          }
          case 48: {
            JsonFormat = (global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat) input.ReadEnum();
            break;
          }
          case 56: {
            EnforceNamingStyle = (global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle) input.ReadEnum();
            break;
          }
          case 64: {
            DefaultSymbolVisibility = (global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility) input.ReadEnum();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 8: {
            FieldPresence = (global::Google.Protobuf.Reflection.FeatureSet.Types.FieldPresence) input.ReadEnum();
            break;
          }
          case 16: {
            EnumType = (global::Google.Protobuf.Reflection.FeatureSet.Types.EnumType) input.ReadEnum();
            break;
          }
          case 24: {
            RepeatedFieldEncoding = (global::Google.Protobuf.Reflection.FeatureSet.Types.RepeatedFieldEncoding) input.ReadEnum();
            break;
          }
          case 32: {
            Utf8Validation = (global::Google.Protobuf.Reflection.FeatureSet.Types.Utf8Validation) input.ReadEnum();
            break;
          }
          case 40: {
            MessageEncoding = (global::Google.Protobuf.Reflection.FeatureSet.Types.MessageEncoding) input.ReadEnum();
            break;
          }
          case 48: {
            JsonFormat = (global::Google.Protobuf.Reflection.FeatureSet.Types.JsonFormat) input.ReadEnum();
            break;
          }
          case 56: {
            EnforceNamingStyle = (global::Google.Protobuf.Reflection.FeatureSet.Types.EnforceNamingStyle) input.ReadEnum();
            break;
          }
          case 64: {
            DefaultSymbolVisibility = (global::Google.Protobuf.Reflection.FeatureSet.Types.VisibilityFeature.Types.DefaultSymbolVisibility) input.ReadEnum();
            break;
          }
        }
      }
    }
    #endif

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

    #region Nested types
    /// <summary>Container for nested types declared in the FeatureSet message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      public enum FieldPresence {
        [pbr::OriginalName("FIELD_PRESENCE_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("EXPLICIT")] Explicit = 1,
        [pbr::OriginalName("IMPLICIT")] Implicit = 2,
        [pbr::OriginalName("LEGACY_REQUIRED")] LegacyRequired = 3,
      }

      public enum EnumType {
        [pbr::OriginalName("ENUM_TYPE_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("OPEN")] Open = 1,
        [pbr::OriginalName("CLOSED")] Closed = 2,
      }

      public enum RepeatedFieldEncoding {
        [pbr::OriginalName("REPEATED_FIELD_ENCODING_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("PACKED")] Packed = 1,
        [pbr::OriginalName("EXPANDED")] Expanded = 2,
      }

      public enum Utf8Validation {
        [pbr::OriginalName("UTF8_VALIDATION_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("VERIFY")] Verify = 2,
        [pbr::OriginalName("NONE")] None = 3,
      }

      public enum MessageEncoding {
        [pbr::OriginalName("MESSAGE_ENCODING_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("LENGTH_PREFIXED")] LengthPrefixed = 1,
        [pbr::OriginalName("DELIMITED")] Delimited = 2,
      }

      public enum JsonFormat {
        [pbr::OriginalName("JSON_FORMAT_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("ALLOW")] Allow = 1,
        [pbr::OriginalName("LEGACY_BEST_EFFORT")] LegacyBestEffort = 2,
      }

      public enum EnforceNamingStyle {
        [pbr::OriginalName("ENFORCE_NAMING_STYLE_UNKNOWN")] Unknown = 0,
        [pbr::OriginalName("STYLE2024")] Style2024 = 1,
        [pbr::OriginalName("STYLE_LEGACY")] StyleLegacy = 2,
      }

      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class VisibilityFeature : pb::IMessage<VisibilityFeature>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<VisibilityFeature> _parser = new pb::MessageParser<VisibilityFeature>(() => new VisibilityFeature());
        private pb::UnknownFieldSet _unknownFields;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<VisibilityFeature> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.FeatureSet.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public VisibilityFeature() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public VisibilityFeature(VisibilityFeature other) : this() {
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public VisibilityFeature Clone() {
          return new VisibilityFeature(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as VisibilityFeature);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Equals(VisibilityFeature other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override int GetHashCode() {
          int hash = 1;
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public int CalculateSize() {
          int size = 0;
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(VisibilityFeature other) {
          if (other == null) {
            return;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
            }
          }
        }
        #endif

        #region Nested types
        /// <summary>Container for nested types declared in the VisibilityFeature message type.</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static partial class Types {
          public enum DefaultSymbolVisibility {
            [pbr::OriginalName("DEFAULT_SYMBOL_VISIBILITY_UNKNOWN")] Unknown = 0,
            /// <summary>
            /// Default pre-EDITION_2024, all UNSET visibility are export.
            /// </summary>
            [pbr::OriginalName("EXPORT_ALL")] ExportAll = 1,
            /// <summary>
            /// All top-level symbols default to export, nested default to local.
            /// </summary>
            [pbr::OriginalName("EXPORT_TOP_LEVEL")] ExportTopLevel = 2,
            /// <summary>
            /// All symbols default to local.
            /// </summary>
            [pbr::OriginalName("LOCAL_ALL")] LocalAll = 3,
            /// <summary>
            /// All symbols local by default. Nested types cannot be exported.
            /// With special case caveat for message { enum {} reserved 1 to max; }
            /// This is the recommended setting for new protos.
            /// </summary>
            [pbr::OriginalName("STRICT")] Strict = 4,
          }

        }
        #endregion

      }

    }
    #endregion

  }

  /// <summary>
  /// A compiled specification for the defaults of a set of features.  These
  /// messages are generated from FeatureSet extensions and can be used to seed
  /// feature resolution. The resolution with this object becomes a simple search
  /// for the closest matching edition, followed by proto merges.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class FeatureSetDefaults : pb::IMessage<FeatureSetDefaults>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<FeatureSetDefaults> _parser = new pb::MessageParser<FeatureSetDefaults>(() => new FeatureSetDefaults());
    private pb::UnknownFieldSet _unknownFields;
    private int _hasBits0;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<FeatureSetDefaults> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[20]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FeatureSetDefaults() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FeatureSetDefaults(FeatureSetDefaults other) : this() {
      _hasBits0 = other._hasBits0;
      defaults_ = other.defaults_.Clone();
      minimumEdition_ = other.minimumEdition_;
      maximumEdition_ = other.maximumEdition_;
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public FeatureSetDefaults Clone() {
      return new FeatureSetDefaults(this);
    }

    /// <summary>Field number for the "defaults" field.</summary>
    public const int DefaultsFieldNumber = 1;
    private static readonly pb::FieldCodec<global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault> _repeated_defaults_codec
        = pb::FieldCodec.ForMessage(10, global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault.Parser);
    private readonly pbc::RepeatedField<global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault> defaults_ = new pbc::RepeatedField<global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault>();
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.FeatureSetDefaults.Types.FeatureSetEditionDefault> Defaults {
      get { return defaults_; }
    }

    /// <summary>Field number for the "minimum_edition" field.</summary>
    public const int MinimumEditionFieldNumber = 4;
    private readonly static global::Google.Protobuf.Reflection.Edition MinimumEditionDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

    private global::Google.Protobuf.Reflection.Edition minimumEdition_;
    /// <summary>
    /// The minimum supported edition (inclusive) when this was constructed.
    /// Editions before this will not have defaults.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.Edition MinimumEdition {
      get { if ((_hasBits0 & 1) != 0) { return minimumEdition_; } else { return MinimumEditionDefaultValue; } }
      set {
        _hasBits0 |= 1;
        minimumEdition_ = value;
      }
    }
    /// <summary>Gets whether the "minimum_edition" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasMinimumEdition {
      get { return (_hasBits0 & 1) != 0; }
    }
    /// <summary>Clears the value of the "minimum_edition" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearMinimumEdition() {
      _hasBits0 &= ~1;
    }

    /// <summary>Field number for the "maximum_edition" field.</summary>
    public const int MaximumEditionFieldNumber = 5;
    private readonly static global::Google.Protobuf.Reflection.Edition MaximumEditionDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

    private global::Google.Protobuf.Reflection.Edition maximumEdition_;
    /// <summary>
    /// The maximum known edition (inclusive) when this was constructed. Editions
    /// after this will not have reliable defaults.
    /// </summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public global::Google.Protobuf.Reflection.Edition MaximumEdition {
      get { if ((_hasBits0 & 2) != 0) { return maximumEdition_; } else { return MaximumEditionDefaultValue; } }
      set {
        _hasBits0 |= 2;
        maximumEdition_ = value;
      }
    }
    /// <summary>Gets whether the "maximum_edition" field is set</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool HasMaximumEdition {
      get { return (_hasBits0 & 2) != 0; }
    }
    /// <summary>Clears the value of the "maximum_edition" field</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void ClearMaximumEdition() {
      _hasBits0 &= ~2;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as FeatureSetDefaults);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public bool Equals(FeatureSetDefaults other) {
      if (ReferenceEquals(other, null)) {
        return false;
      }
      if (ReferenceEquals(other, this)) {
        return true;
      }
      if(!defaults_.Equals(other.defaults_)) return false;
      if (MinimumEdition != other.MinimumEdition) return false;
      if (MaximumEdition != other.MaximumEdition) return false;
      return Equals(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= defaults_.GetHashCode();
      if (HasMinimumEdition) hash ^= MinimumEdition.GetHashCode();
      if (HasMaximumEdition) hash ^= MaximumEdition.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      defaults_.WriteTo(output, _repeated_defaults_codec);
      if (HasMinimumEdition) {
        output.WriteRawTag(32);
        output.WriteEnum((int) MinimumEdition);
      }
      if (HasMaximumEdition) {
        output.WriteRawTag(40);
        output.WriteEnum((int) MaximumEdition);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      defaults_.WriteTo(ref output, _repeated_defaults_codec);
      if (HasMinimumEdition) {
        output.WriteRawTag(32);
        output.WriteEnum((int) MinimumEdition);
      }
      if (HasMaximumEdition) {
        output.WriteRawTag(40);
        output.WriteEnum((int) MaximumEdition);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      size += defaults_.CalculateSize(_repeated_defaults_codec);
      if (HasMinimumEdition) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) MinimumEdition);
      }
      if (HasMaximumEdition) {
        size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) MaximumEdition);
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(FeatureSetDefaults other) {
      if (other == null) {
        return;
      }
      defaults_.Add(other.defaults_);
      if (other.HasMinimumEdition) {
        MinimumEdition = other.MinimumEdition;
      }
      if (other.HasMaximumEdition) {
        MaximumEdition = other.MaximumEdition;
      }
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            defaults_.AddEntriesFrom(input, _repeated_defaults_codec);
            break;
          }
          case 32: {
            MinimumEdition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
            break;
          }
          case 40: {
            MaximumEdition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            defaults_.AddEntriesFrom(ref input, _repeated_defaults_codec);
            break;
          }
          case 32: {
            MinimumEdition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
            break;
          }
          case 40: {
            MaximumEdition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the FeatureSetDefaults message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      /// <summary>
      /// A map from every known edition with a unique set of defaults to its
      /// defaults. Not all editions may be contained here.  For a given edition,
      /// the defaults at the closest matching edition ordered at or before it should
      /// be used.  This field must be in strict ascending order by edition.
      /// </summary>
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class FeatureSetEditionDefault : pb::IMessage<FeatureSetEditionDefault>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<FeatureSetEditionDefault> _parser = new pb::MessageParser<FeatureSetEditionDefault>(() => new FeatureSetEditionDefault());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<FeatureSetEditionDefault> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.FeatureSetDefaults.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public FeatureSetEditionDefault() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public FeatureSetEditionDefault(FeatureSetEditionDefault other) : this() {
          _hasBits0 = other._hasBits0;
          edition_ = other.edition_;
          overridableFeatures_ = other.overridableFeatures_ != null ? other.overridableFeatures_.Clone() : null;
          fixedFeatures_ = other.fixedFeatures_ != null ? other.fixedFeatures_.Clone() : null;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public FeatureSetEditionDefault Clone() {
          return new FeatureSetEditionDefault(this);
        }

        /// <summary>Field number for the "edition" field.</summary>
        public const int EditionFieldNumber = 3;
        private readonly static global::Google.Protobuf.Reflection.Edition EditionDefaultValue = global::Google.Protobuf.Reflection.Edition.Unknown;

        private global::Google.Protobuf.Reflection.Edition edition_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.Edition Edition {
          get { if ((_hasBits0 & 1) != 0) { return edition_; } else { return EditionDefaultValue; } }
          set {
            _hasBits0 |= 1;
            edition_ = value;
          }
        }
        /// <summary>Gets whether the "edition" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEdition {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "edition" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEdition() {
          _hasBits0 &= ~1;
        }

        /// <summary>Field number for the "overridable_features" field.</summary>
        public const int OverridableFeaturesFieldNumber = 4;
        private global::Google.Protobuf.Reflection.FeatureSet overridableFeatures_;
        /// <summary>
        /// Defaults of features that can be overridden in this edition.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.FeatureSet OverridableFeatures {
          get { return overridableFeatures_; }
          set {
            overridableFeatures_ = value;
          }
        }

        /// <summary>Field number for the "fixed_features" field.</summary>
        public const int FixedFeaturesFieldNumber = 5;
        private global::Google.Protobuf.Reflection.FeatureSet fixedFeatures_;
        /// <summary>
        /// Defaults of features that can't be overridden in this edition.
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.FeatureSet FixedFeatures {
          get { return fixedFeatures_; }
          set {
            fixedFeatures_ = value;
          }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as FeatureSetEditionDefault);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool Equals(FeatureSetEditionDefault other) {
          if (ReferenceEquals(other, null)) {
            return false;
          }
          if (ReferenceEquals(other, this)) {
            return true;
          }
          if (Edition != other.Edition) return false;
          if (!object.Equals(OverridableFeatures, other.OverridableFeatures)) return false;
          if (!object.Equals(FixedFeatures, other.FixedFeatures)) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override int GetHashCode() {
          int hash = 1;
          if (HasEdition) hash ^= Edition.GetHashCode();
          if (overridableFeatures_ != null) hash ^= OverridableFeatures.GetHashCode();
          if (fixedFeatures_ != null) hash ^= FixedFeatures.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          if (HasEdition) {
            output.WriteRawTag(24);
            output.WriteEnum((int) Edition);
          }
          if (overridableFeatures_ != null) {
            output.WriteRawTag(34);
            output.WriteMessage(OverridableFeatures);
          }
          if (fixedFeatures_ != null) {
            output.WriteRawTag(42);
            output.WriteMessage(FixedFeatures);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          if (HasEdition) {
            output.WriteRawTag(24);
            output.WriteEnum((int) Edition);
          }
          if (overridableFeatures_ != null) {
            output.WriteRawTag(34);
            output.WriteMessage(OverridableFeatures);
          }
          if (fixedFeatures_ != null) {
            output.WriteRawTag(42);
            output.WriteMessage(FixedFeatures);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public int CalculateSize() {
          int size = 0;
          if (HasEdition) {
            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Edition);
          }
          if (overridableFeatures_ != null) {
            size += 1 + pb::CodedOutputStream.ComputeMessageSize(OverridableFeatures);
          }
          if (fixedFeatures_ != null) {
            size += 1 + pb::CodedOutputStream.ComputeMessageSize(FixedFeatures);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(FeatureSetEditionDefault other) {
          if (other == null) {
            return;
          }
          if (other.HasEdition) {
            Edition = other.Edition;
          }
          if (other.overridableFeatures_ != null) {
            if (overridableFeatures_ == null) {
              OverridableFeatures = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            OverridableFeatures.MergeFrom(other.OverridableFeatures);
          }
          if (other.fixedFeatures_ != null) {
            if (fixedFeatures_ == null) {
              FixedFeatures = new global::Google.Protobuf.Reflection.FeatureSet();
            }
            FixedFeatures.MergeFrom(other.FixedFeatures);
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
                break;
              case 24: {
                Edition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
              case 34: {
                if (overridableFeatures_ == null) {
                  OverridableFeatures = new global::Google.Protobuf.Reflection.FeatureSet();
                }
                input.ReadMessage(OverridableFeatures);
                break;
              }
              case 42: {
                if (fixedFeatures_ == null) {
                  FixedFeatures = new global::Google.Protobuf.Reflection.FeatureSet();
                }
                input.ReadMessage(FixedFeatures);
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 24: {
                Edition = (global::Google.Protobuf.Reflection.Edition) input.ReadEnum();
                break;
              }
              case 34: {
                if (overridableFeatures_ == null) {
                  OverridableFeatures = new global::Google.Protobuf.Reflection.FeatureSet();
                }
                input.ReadMessage(OverridableFeatures);
                break;
              }
              case 42: {
                if (fixedFeatures_ == null) {
                  FixedFeatures = new global::Google.Protobuf.Reflection.FeatureSet();
                }
                input.ReadMessage(FixedFeatures);
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #endregion

  }

  /// <summary>
  /// Encapsulates information about the original source file from which a
  /// FileDescriptorProto was generated.
  /// </summary>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class SourceCodeInfo : pb::IExtendableMessage<SourceCodeInfo>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<SourceCodeInfo> _parser = new pb::MessageParser<SourceCodeInfo>(() => new SourceCodeInfo());
    private pb::UnknownFieldSet _unknownFields;
    internal pb::ExtensionSet<SourceCodeInfo> _extensions;
    private pb::ExtensionSet<SourceCodeInfo> _Extensions { get { return _extensions; } }
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<SourceCodeInfo> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[21]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public SourceCodeInfo() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public SourceCodeInfo(SourceCodeInfo other) : this() {
      location_ = other.location_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
      _extensions = pb::ExtensionSet.Clone(other._extensions);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.SourceCodeInfo.Types.Location> Location {
      get { return location_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as SourceCodeInfo);
    }

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= location_.GetHashCode();
      if (_extensions != null) {
        hash ^= _extensions.GetHashCode();
      }
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      location_.WriteTo(output, _repeated_location_codec);
      if (_extensions != null) {
        _extensions.WriteTo(output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      location_.WriteTo(ref output, _repeated_location_codec);
      if (_extensions != null) {
        _extensions.WriteTo(ref output);
      }
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public int CalculateSize() {
      int size = 0;
      size += location_.CalculateSize(_repeated_location_codec);
      if (_extensions != null) {
        size += _extensions.CalculateSize();
      }
      if (_unknownFields != null) {
        size += _unknownFields.CalculateSize();
      }
      return size;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(SourceCodeInfo other) {
      if (other == null) {
        return;
      }
      location_.Add(other.location_);
      pb::ExtensionSet.MergeFrom(ref _extensions, other._extensions);
      _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            }
            break;
          case 10: {
            location_.AddEntriesFrom(input, _repeated_location_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            if (!pb::ExtensionSet.TryMergeFieldFrom(ref _extensions, ref input)) {
              _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            }
            break;
          case 10: {
            location_.AddEntriesFrom(ref input, _repeated_location_codec);
            break;
          }
        }
      }
    }
    #endif

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

    #region Nested types
    /// <summary>Container for nested types declared in the SourceCodeInfo message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class Location : pb::IMessage<Location>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<Location> _parser = new pb::MessageParser<Location>(() => new Location());
        private pb::UnknownFieldSet _unknownFields;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<Location> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.SourceCodeInfo.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public Location() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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 appears.
        /// 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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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 moo.
        ///   //
        ///   // Another line attached to moo.
        ///   optional double moo = 4;
        ///
        ///   // Detached comment for corge. This is not leading or trailing comments
        ///   // to moo 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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasLeadingComments {
          get { return leadingComments_ != null; }
        }
        /// <summary>Clears the value of the "leading_comments" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasTrailingComments {
          get { return trailingComments_ != null; }
        }
        /// <summary>Clears the value of the "trailing_comments" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public pbc::RepeatedField<string> LeadingDetachedComments {
          get { return leadingDetachedComments_; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as Location);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          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);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          path_.WriteTo(ref output, _repeated_path_codec);
          span_.WriteTo(ref output, _repeated_span_codec);
          if (HasLeadingComments) {
            output.WriteRawTag(26);
            output.WriteString(LeadingComments);
          }
          if (HasTrailingComments) {
            output.WriteRawTag(34);
            output.WriteString(TrailingComments);
          }
          leadingDetachedComments_.WriteTo(ref output, _repeated_leadingDetachedComments_codec);
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          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;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 10:
              case 8: {
                path_.AddEntriesFrom(ref input, _repeated_path_codec);
                break;
              }
              case 18:
              case 16: {
                span_.AddEntriesFrom(ref input, _repeated_span_codec);
                break;
              }
              case 26: {
                LeadingComments = input.ReadString();
                break;
              }
              case 34: {
                TrailingComments = input.ReadString();
                break;
              }
              case 50: {
                leadingDetachedComments_.AddEntriesFrom(ref input, _repeated_leadingDetachedComments_codec);
                break;
              }
            }
          }
        }
        #endif

      }

    }
    #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>
  [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
  public sealed partial class GeneratedCodeInfo : pb::IMessage<GeneratedCodeInfo>
  #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      , pb::IBufferMessage
  #endif
  {
    private static readonly pb::MessageParser<GeneratedCodeInfo> _parser = new pb::MessageParser<GeneratedCodeInfo>(() => new GeneratedCodeInfo());
    private pb::UnknownFieldSet _unknownFields;
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pb::MessageParser<GeneratedCodeInfo> Parser { get { return _parser; } }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static pbr::MessageDescriptor Descriptor {
      get { return global::Google.Protobuf.Reflection.DescriptorReflection.Descriptor.MessageTypes[22]; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    pbr::MessageDescriptor pb::IMessage.Descriptor {
      get { return Descriptor; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public GeneratedCodeInfo() {
      OnConstruction();
    }

    partial void OnConstruction();

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public GeneratedCodeInfo(GeneratedCodeInfo other) : this() {
      annotation_ = other.annotation_.Clone();
      _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public pbc::RepeatedField<global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation> Annotation {
      get { return annotation_; }
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override bool Equals(object other) {
      return Equals(other as GeneratedCodeInfo);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    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]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override int GetHashCode() {
      int hash = 1;
      hash ^= annotation_.GetHashCode();
      if (_unknownFields != null) {
        hash ^= _unknownFields.GetHashCode();
      }
      return hash;
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public override string ToString() {
      return pb::JsonFormatter.ToDiagnosticString(this);
    }

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void WriteTo(pb::CodedOutputStream output) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      output.WriteRawMessage(this);
    #else
      annotation_.WriteTo(output, _repeated_annotation_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(output);
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
      annotation_.WriteTo(ref output, _repeated_annotation_codec);
      if (_unknownFields != null) {
        _unknownFields.WriteTo(ref output);
      }
    }
    #endif

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

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

    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public void MergeFrom(pb::CodedInputStream input) {
    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
      input.ReadRawMessage(this);
    #else
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, input);
            break;
          case 10: {
            annotation_.AddEntriesFrom(input, _repeated_annotation_codec);
            break;
          }
        }
      }
    #endif
    }

    #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
      uint tag;
      while ((tag = input.ReadTag()) != 0) {
      if ((tag & 7) == 4) {
        // Abort on any end group tag.
        return;
      }
      switch(tag) {
          default:
            _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
            break;
          case 10: {
            annotation_.AddEntriesFrom(ref input, _repeated_annotation_codec);
            break;
          }
        }
      }
    }
    #endif

    #region Nested types
    /// <summary>Container for nested types declared in the GeneratedCodeInfo message type.</summary>
    [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
    [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
    public static partial class Types {
      [global::System.Diagnostics.DebuggerDisplayAttribute("{ToString(),nq}")]
      public sealed partial class Annotation : pb::IMessage<Annotation>
      #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          , pb::IBufferMessage
      #endif
      {
        private static readonly pb::MessageParser<Annotation> _parser = new pb::MessageParser<Annotation>(() => new Annotation());
        private pb::UnknownFieldSet _unknownFields;
        private int _hasBits0;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pb::MessageParser<Annotation> Parser { get { return _parser; } }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static pbr::MessageDescriptor Descriptor {
          get { return global::Google.Protobuf.Reflection.GeneratedCodeInfo.Descriptor.NestedTypes[0]; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        pbr::MessageDescriptor pb::IMessage.Descriptor {
          get { return Descriptor; }
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public Annotation() {
          OnConstruction();
        }

        partial void OnConstruction();

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public Annotation(Annotation other) : this() {
          _hasBits0 = other._hasBits0;
          path_ = other.path_.Clone();
          sourceFile_ = other.sourceFile_;
          begin_ = other.begin_;
          end_ = other.end_;
          semantic_ = other.semantic_;
          _unknownFields = pb::UnknownFieldSet.Clone(other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasSourceFile {
          get { return sourceFile_ != null; }
        }
        /// <summary>Clears the value of the "source_file" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasBegin {
          get { return (_hasBits0 & 1) != 0; }
        }
        /// <summary>Clears the value of the "begin" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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 object. The end offset should be one past
        /// the last relevant byte (so the length of the text = end - begin).
        /// </summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasEnd {
          get { return (_hasBits0 & 2) != 0; }
        }
        /// <summary>Clears the value of the "end" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearEnd() {
          _hasBits0 &= ~2;
        }

        /// <summary>Field number for the "semantic" field.</summary>
        public const int SemanticFieldNumber = 5;
        private readonly static global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic SemanticDefaultValue = global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic.None;

        private global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic semantic_;
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic Semantic {
          get { if ((_hasBits0 & 4) != 0) { return semantic_; } else { return SemanticDefaultValue; } }
          set {
            _hasBits0 |= 4;
            semantic_ = value;
          }
        }
        /// <summary>Gets whether the "semantic" field is set</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public bool HasSemantic {
          get { return (_hasBits0 & 4) != 0; }
        }
        /// <summary>Clears the value of the "semantic" field</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void ClearSemantic() {
          _hasBits0 &= ~4;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override bool Equals(object other) {
          return Equals(other as Annotation);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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;
          if (Semantic != other.Semantic) return false;
          return Equals(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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 (HasSemantic) hash ^= Semantic.GetHashCode();
          if (_unknownFields != null) {
            hash ^= _unknownFields.GetHashCode();
          }
          return hash;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public override string ToString() {
          return pb::JsonFormatter.ToDiagnosticString(this);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void WriteTo(pb::CodedOutputStream output) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          output.WriteRawMessage(this);
        #else
          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 (HasSemantic) {
            output.WriteRawTag(40);
            output.WriteEnum((int) Semantic);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(output);
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalWriteTo(ref pb::WriteContext output) {
          path_.WriteTo(ref 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 (HasSemantic) {
            output.WriteRawTag(40);
            output.WriteEnum((int) Semantic);
          }
          if (_unknownFields != null) {
            _unknownFields.WriteTo(ref output);
          }
        }
        #endif

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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 (HasSemantic) {
            size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Semantic);
          }
          if (_unknownFields != null) {
            size += _unknownFields.CalculateSize();
          }
          return size;
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        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;
          }
          if (other.HasSemantic) {
            Semantic = other.Semantic;
          }
          _unknownFields = pb::UnknownFieldSet.MergeFrom(_unknownFields, other._unknownFields);
        }

        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public void MergeFrom(pb::CodedInputStream input) {
        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
          input.ReadRawMessage(this);
        #else
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          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;
              }
              case 40: {
                Semantic = (global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic) input.ReadEnum();
                break;
              }
            }
          }
        #endif
        }

        #if !GOOGLE_PROTOBUF_REFSTRUCT_COMPATIBILITY_MODE
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        void pb::IBufferMessage.InternalMergeFrom(ref pb::ParseContext input) {
          uint tag;
          while ((tag = input.ReadTag()) != 0) {
          if ((tag & 7) == 4) {
            // Abort on any end group tag.
            return;
          }
          switch(tag) {
              default:
                _unknownFields = pb::UnknownFieldSet.MergeFieldFrom(_unknownFields, ref input);
                break;
              case 10:
              case 8: {
                path_.AddEntriesFrom(ref input, _repeated_path_codec);
                break;
              }
              case 18: {
                SourceFile = input.ReadString();
                break;
              }
              case 24: {
                Begin = input.ReadInt32();
                break;
              }
              case 32: {
                End = input.ReadInt32();
                break;
              }
              case 40: {
                Semantic = (global::Google.Protobuf.Reflection.GeneratedCodeInfo.Types.Annotation.Types.Semantic) input.ReadEnum();
                break;
              }
            }
          }
        }
        #endif

        #region Nested types
        /// <summary>Container for nested types declared in the Annotation message type.</summary>
        [global::System.Diagnostics.DebuggerNonUserCodeAttribute]
        [global::System.CodeDom.Compiler.GeneratedCode("protoc", null)]
        public static partial class Types {
          /// <summary>
          /// Represents the identified object's effect on the element in the original
          /// .proto file.
          /// </summary>
          public enum Semantic {
            /// <summary>
            /// There is no effect or the effect is indescribable.
            /// </summary>
            [pbr::OriginalName("NONE")] None = 0,
            /// <summary>
            /// The element is set or otherwise mutated.
            /// </summary>
            [pbr::OriginalName("SET")] Set = 1,
            /// <summary>
            /// An alias to the element is returned.
            /// </summary>
            [pbr::OriginalName("ALIAS")] Alias = 2,
          }

        }
        #endregion

      }

    }
    #endregion

  }

  #endregion

}

#endregion Designer generated code
