// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: google/protobuf/descriptor.proto

#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "google/protobuf/descriptor.pb.h"

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/descriptor.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/reflection_ops.h>
#include <google/protobuf/wire_format.h>
// @@protoc_insertion_point(includes)

namespace google {
namespace protobuf {

namespace {

const ::google::protobuf::Descriptor* FileDescriptorSet_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  FileDescriptorSet_reflection_ = NULL;
const ::google::protobuf::Descriptor* FileDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  FileDescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* DescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  DescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  DescriptorProto_ExtensionRange_reflection_ = NULL;
const ::google::protobuf::Descriptor* FieldDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  FieldDescriptorProto_reflection_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor_ = NULL;
const ::google::protobuf::Descriptor* EnumDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  EnumDescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* EnumValueDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  EnumValueDescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* ServiceDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  ServiceDescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* MethodDescriptorProto_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MethodDescriptorProto_reflection_ = NULL;
const ::google::protobuf::Descriptor* FileOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  FileOptions_reflection_ = NULL;
const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor_ = NULL;
const ::google::protobuf::Descriptor* MessageOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MessageOptions_reflection_ = NULL;
const ::google::protobuf::Descriptor* FieldOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  FieldOptions_reflection_ = NULL;
const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor_ = NULL;
const ::google::protobuf::Descriptor* EnumOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  EnumOptions_reflection_ = NULL;
const ::google::protobuf::Descriptor* EnumValueOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  EnumValueOptions_reflection_ = NULL;
const ::google::protobuf::Descriptor* ServiceOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  ServiceOptions_reflection_ = NULL;
const ::google::protobuf::Descriptor* MethodOptions_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  MethodOptions_reflection_ = NULL;
const ::google::protobuf::Descriptor* UninterpretedOption_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  UninterpretedOption_reflection_ = NULL;
const ::google::protobuf::Descriptor* UninterpretedOption_NamePart_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  UninterpretedOption_NamePart_reflection_ = NULL;
const ::google::protobuf::Descriptor* SourceCodeInfo_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  SourceCodeInfo_reflection_ = NULL;
const ::google::protobuf::Descriptor* SourceCodeInfo_Location_descriptor_ = NULL;
const ::google::protobuf::internal::GeneratedMessageReflection*
  SourceCodeInfo_Location_reflection_ = NULL;

}  // namespace


void protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto() {
  protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  const ::google::protobuf::FileDescriptor* file =
    ::google::protobuf::DescriptorPool::generated_pool()->FindFileByName(
      "google/protobuf/descriptor.proto");
  GOOGLE_CHECK(file != NULL);
  FileDescriptorSet_descriptor_ = file->message_type(0);
  static const int FileDescriptorSet_offsets_[1] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, file_),
  };
  FileDescriptorSet_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      FileDescriptorSet_descriptor_,
      FileDescriptorSet::default_instance_,
      FileDescriptorSet_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorSet, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(FileDescriptorSet));
  FileDescriptorProto_descriptor_ = file->message_type(1);
  static const int FileDescriptorProto_offsets_[11] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, package_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, dependency_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, public_dependency_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, weak_dependency_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, message_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, enum_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, service_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, extension_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, options_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, source_code_info_),
  };
  FileDescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      FileDescriptorProto_descriptor_,
      FileDescriptorProto::default_instance_,
      FileDescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileDescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(FileDescriptorProto));
  DescriptorProto_descriptor_ = file->message_type(2);
  static const int DescriptorProto_offsets_[7] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, field_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, nested_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, enum_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, extension_range_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, options_),
  };
  DescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      DescriptorProto_descriptor_,
      DescriptorProto::default_instance_,
      DescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(DescriptorProto));
  DescriptorProto_ExtensionRange_descriptor_ = DescriptorProto_descriptor_->nested_type(0);
  static const int DescriptorProto_ExtensionRange_offsets_[2] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, start_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, end_),
  };
  DescriptorProto_ExtensionRange_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      DescriptorProto_ExtensionRange_descriptor_,
      DescriptorProto_ExtensionRange::default_instance_,
      DescriptorProto_ExtensionRange_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(DescriptorProto_ExtensionRange, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(DescriptorProto_ExtensionRange));
  FieldDescriptorProto_descriptor_ = file->message_type(3);
  static const int FieldDescriptorProto_offsets_[8] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, number_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, label_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, type_name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, extendee_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, default_value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, options_),
  };
  FieldDescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      FieldDescriptorProto_descriptor_,
      FieldDescriptorProto::default_instance_,
      FieldDescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldDescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(FieldDescriptorProto));
  FieldDescriptorProto_Type_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(0);
  FieldDescriptorProto_Label_descriptor_ = FieldDescriptorProto_descriptor_->enum_type(1);
  EnumDescriptorProto_descriptor_ = file->message_type(4);
  static const int EnumDescriptorProto_offsets_[3] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, options_),
  };
  EnumDescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      EnumDescriptorProto_descriptor_,
      EnumDescriptorProto::default_instance_,
      EnumDescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumDescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(EnumDescriptorProto));
  EnumValueDescriptorProto_descriptor_ = file->message_type(5);
  static const int EnumValueDescriptorProto_offsets_[3] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, number_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, options_),
  };
  EnumValueDescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      EnumValueDescriptorProto_descriptor_,
      EnumValueDescriptorProto::default_instance_,
      EnumValueDescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueDescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(EnumValueDescriptorProto));
  ServiceDescriptorProto_descriptor_ = file->message_type(6);
  static const int ServiceDescriptorProto_offsets_[3] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, method_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, options_),
  };
  ServiceDescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      ServiceDescriptorProto_descriptor_,
      ServiceDescriptorProto::default_instance_,
      ServiceDescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceDescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(ServiceDescriptorProto));
  MethodDescriptorProto_descriptor_ = file->message_type(7);
  static const int MethodDescriptorProto_offsets_[4] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, input_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, output_type_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, options_),
  };
  MethodDescriptorProto_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MethodDescriptorProto_descriptor_,
      MethodDescriptorProto::default_instance_,
      MethodDescriptorProto_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodDescriptorProto, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MethodDescriptorProto));
  FileOptions_descriptor_ = file->message_type(8);
  static const int FileOptions_offsets_[10] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generate_equals_and_hash_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, optimize_for_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, go_package_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, cc_generic_services_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_generic_services_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, py_generic_services_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, uninterpreted_option_),
  };
  FileOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      FileOptions_descriptor_,
      FileOptions::default_instance_,
      FileOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(FileOptions));
  FileOptions_OptimizeMode_descriptor_ = FileOptions_descriptor_->enum_type(0);
  MessageOptions_descriptor_ = file->message_type(9);
  static const int MessageOptions_offsets_[3] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, message_set_wire_format_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, no_standard_descriptor_accessor_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, uninterpreted_option_),
  };
  MessageOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MessageOptions_descriptor_,
      MessageOptions::default_instance_,
      MessageOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MessageOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MessageOptions));
  FieldOptions_descriptor_ = file->message_type(10);
  static const int FieldOptions_offsets_[7] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, lazy_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, deprecated_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, experimental_map_key_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, weak_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, uninterpreted_option_),
  };
  FieldOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      FieldOptions_descriptor_,
      FieldOptions::default_instance_,
      FieldOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(FieldOptions));
  FieldOptions_CType_descriptor_ = FieldOptions_descriptor_->enum_type(0);
  EnumOptions_descriptor_ = file->message_type(11);
  static const int EnumOptions_offsets_[2] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, allow_alias_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, uninterpreted_option_),
  };
  EnumOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      EnumOptions_descriptor_,
      EnumOptions::default_instance_,
      EnumOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(EnumOptions));
  EnumValueOptions_descriptor_ = file->message_type(12);
  static const int EnumValueOptions_offsets_[1] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, uninterpreted_option_),
  };
  EnumValueOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      EnumValueOptions_descriptor_,
      EnumValueOptions::default_instance_,
      EnumValueOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(EnumValueOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(EnumValueOptions));
  ServiceOptions_descriptor_ = file->message_type(13);
  static const int ServiceOptions_offsets_[1] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, uninterpreted_option_),
  };
  ServiceOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      ServiceOptions_descriptor_,
      ServiceOptions::default_instance_,
      ServiceOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(ServiceOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(ServiceOptions));
  MethodOptions_descriptor_ = file->message_type(14);
  static const int MethodOptions_offsets_[1] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, uninterpreted_option_),
  };
  MethodOptions_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      MethodOptions_descriptor_,
      MethodOptions::default_instance_,
      MethodOptions_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _unknown_fields_),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(MethodOptions, _extensions_),
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(MethodOptions));
  UninterpretedOption_descriptor_ = file->message_type(15);
  static const int UninterpretedOption_offsets_[7] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, name_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, identifier_value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, positive_int_value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, negative_int_value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, double_value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, string_value_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, aggregate_value_),
  };
  UninterpretedOption_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      UninterpretedOption_descriptor_,
      UninterpretedOption::default_instance_,
      UninterpretedOption_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(UninterpretedOption));
  UninterpretedOption_NamePart_descriptor_ = UninterpretedOption_descriptor_->nested_type(0);
  static const int UninterpretedOption_NamePart_offsets_[2] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, name_part_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, is_extension_),
  };
  UninterpretedOption_NamePart_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      UninterpretedOption_NamePart_descriptor_,
      UninterpretedOption_NamePart::default_instance_,
      UninterpretedOption_NamePart_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(UninterpretedOption_NamePart, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(UninterpretedOption_NamePart));
  SourceCodeInfo_descriptor_ = file->message_type(16);
  static const int SourceCodeInfo_offsets_[1] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, location_),
  };
  SourceCodeInfo_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      SourceCodeInfo_descriptor_,
      SourceCodeInfo::default_instance_,
      SourceCodeInfo_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(SourceCodeInfo));
  SourceCodeInfo_Location_descriptor_ = SourceCodeInfo_descriptor_->nested_type(0);
  static const int SourceCodeInfo_Location_offsets_[4] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, leading_comments_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, trailing_comments_),
  };
  SourceCodeInfo_Location_reflection_ =
    new ::google::protobuf::internal::GeneratedMessageReflection(
      SourceCodeInfo_Location_descriptor_,
      SourceCodeInfo_Location::default_instance_,
      SourceCodeInfo_Location_offsets_,
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _has_bits_[0]),
      GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, _unknown_fields_),
      -1,
      ::google::protobuf::DescriptorPool::generated_pool(),
      ::google::protobuf::MessageFactory::generated_factory(),
      sizeof(SourceCodeInfo_Location));
}

namespace {

GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AssignDescriptors_once_);
inline void protobuf_AssignDescriptorsOnce() {
  ::google::protobuf::GoogleOnceInit(&protobuf_AssignDescriptors_once_,
                 &protobuf_AssignDesc_google_2fprotobuf_2fdescriptor_2eproto);
}

void protobuf_RegisterTypes(const ::std::string&) {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    FileDescriptorSet_descriptor_, &FileDescriptorSet::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    FileDescriptorProto_descriptor_, &FileDescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    DescriptorProto_descriptor_, &DescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    DescriptorProto_ExtensionRange_descriptor_, &DescriptorProto_ExtensionRange::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    FieldDescriptorProto_descriptor_, &FieldDescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    EnumDescriptorProto_descriptor_, &EnumDescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    EnumValueDescriptorProto_descriptor_, &EnumValueDescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    ServiceDescriptorProto_descriptor_, &ServiceDescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MethodDescriptorProto_descriptor_, &MethodDescriptorProto::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    FileOptions_descriptor_, &FileOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MessageOptions_descriptor_, &MessageOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    FieldOptions_descriptor_, &FieldOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    EnumOptions_descriptor_, &EnumOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    EnumValueOptions_descriptor_, &EnumValueOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    ServiceOptions_descriptor_, &ServiceOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    MethodOptions_descriptor_, &MethodOptions::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    UninterpretedOption_descriptor_, &UninterpretedOption::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    UninterpretedOption_NamePart_descriptor_, &UninterpretedOption_NamePart::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    SourceCodeInfo_descriptor_, &SourceCodeInfo::default_instance());
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedMessage(
    SourceCodeInfo_Location_descriptor_, &SourceCodeInfo_Location::default_instance());
}

}  // namespace

void protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto() {
  delete FileDescriptorSet::default_instance_;
  delete FileDescriptorSet_reflection_;
  delete FileDescriptorProto::default_instance_;
  delete FileDescriptorProto_reflection_;
  delete DescriptorProto::default_instance_;
  delete DescriptorProto_reflection_;
  delete DescriptorProto_ExtensionRange::default_instance_;
  delete DescriptorProto_ExtensionRange_reflection_;
  delete FieldDescriptorProto::default_instance_;
  delete FieldDescriptorProto_reflection_;
  delete EnumDescriptorProto::default_instance_;
  delete EnumDescriptorProto_reflection_;
  delete EnumValueDescriptorProto::default_instance_;
  delete EnumValueDescriptorProto_reflection_;
  delete ServiceDescriptorProto::default_instance_;
  delete ServiceDescriptorProto_reflection_;
  delete MethodDescriptorProto::default_instance_;
  delete MethodDescriptorProto_reflection_;
  delete FileOptions::default_instance_;
  delete FileOptions_reflection_;
  delete MessageOptions::default_instance_;
  delete MessageOptions_reflection_;
  delete FieldOptions::default_instance_;
  delete FieldOptions_reflection_;
  delete EnumOptions::default_instance_;
  delete EnumOptions_reflection_;
  delete EnumValueOptions::default_instance_;
  delete EnumValueOptions_reflection_;
  delete ServiceOptions::default_instance_;
  delete ServiceOptions_reflection_;
  delete MethodOptions::default_instance_;
  delete MethodOptions_reflection_;
  delete UninterpretedOption::default_instance_;
  delete UninterpretedOption_reflection_;
  delete UninterpretedOption_NamePart::default_instance_;
  delete UninterpretedOption_NamePart_reflection_;
  delete SourceCodeInfo::default_instance_;
  delete SourceCodeInfo_reflection_;
  delete SourceCodeInfo_Location::default_instance_;
  delete SourceCodeInfo_Location_reflection_;
}

void protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto() {
  static bool already_here = false;
  if (already_here) return;
  already_here = true;
  GOOGLE_PROTOBUF_VERIFY_VERSION;

  ::google::protobuf::DescriptorPool::InternalAddGeneratedFile(
    "\n google/protobuf/descriptor.proto\022\017goog"
    "le.protobuf\"G\n\021FileDescriptorSet\0222\n\004file"
    "\030\001 \003(\0132$.google.protobuf.FileDescriptorP"
    "roto\"\313\003\n\023FileDescriptorProto\022\014\n\004name\030\001 \001"
    "(\t\022\017\n\007package\030\002 \001(\t\022\022\n\ndependency\030\003 \003(\t\022"
    "\031\n\021public_dependency\030\n \003(\005\022\027\n\017weak_depen"
    "dency\030\013 \003(\005\0226\n\014message_type\030\004 \003(\0132 .goog"
    "le.protobuf.DescriptorProto\0227\n\tenum_type"
    "\030\005 \003(\0132$.google.protobuf.EnumDescriptorP"
    "roto\0228\n\007service\030\006 \003(\0132\'.google.protobuf."
    "ServiceDescriptorProto\0228\n\textension\030\007 \003("
    "\0132%.google.protobuf.FieldDescriptorProto"
    "\022-\n\007options\030\010 \001(\0132\034.google.protobuf.File"
    "Options\0229\n\020source_code_info\030\t \001(\0132\037.goog"
    "le.protobuf.SourceCodeInfo\"\251\003\n\017Descripto"
    "rProto\022\014\n\004name\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.go"
    "ogle.protobuf.FieldDescriptorProto\0228\n\tex"
    "tension\030\006 \003(\0132%.google.protobuf.FieldDes"
    "criptorProto\0225\n\013nested_type\030\003 \003(\0132 .goog"
    "le.protobuf.DescriptorProto\0227\n\tenum_type"
    "\030\004 \003(\0132$.google.protobuf.EnumDescriptorP"
    "roto\022H\n\017extension_range\030\005 \003(\0132/.google.p"
    "rotobuf.DescriptorProto.ExtensionRange\0220"
    "\n\007options\030\007 \001(\0132\037.google.protobuf.Messag"
    "eOptions\032,\n\016ExtensionRange\022\r\n\005start\030\001 \001("
    "\005\022\013\n\003end\030\002 \001(\005\"\224\005\n\024FieldDescriptorProto\022"
    "\014\n\004name\030\001 \001(\t\022\016\n\006number\030\003 \001(\005\022:\n\005label\030\004"
    " \001(\0162+.google.protobuf.FieldDescriptorPr"
    "oto.Label\0228\n\004type\030\005 \001(\0162*.google.protobu"
    "f.FieldDescriptorProto.Type\022\021\n\ttype_name"
    "\030\006 \001(\t\022\020\n\010extendee\030\002 \001(\t\022\025\n\rdefault_valu"
    "e\030\007 \001(\t\022.\n\007options\030\010 \001(\0132\035.google.protob"
    "uf.FieldOptions\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020"
    "\001\022\016\n\nTYPE_FLOAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYP"
    "E_UINT64\020\004\022\016\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED"
    "64\020\006\022\020\n\014TYPE_FIXED32\020\007\022\r\n\tTYPE_BOOL\020\010\022\017\n"
    "\013TYPE_STRING\020\t\022\016\n\nTYPE_GROUP\020\n\022\020\n\014TYPE_M"
    "ESSAGE\020\013\022\016\n\nTYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020"
    "\r\022\r\n\tTYPE_ENUM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rT"
    "YPE_SFIXED64\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_"
    "SINT64\020\022\"C\n\005Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n"
    "\016LABEL_REQUIRED\020\002\022\022\n\016LABEL_REPEATED\020\003\"\214\001"
    "\n\023EnumDescriptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005v"
    "alue\030\002 \003(\0132).google.protobuf.EnumValueDe"
    "scriptorProto\022-\n\007options\030\003 \001(\0132\034.google."
    "protobuf.EnumOptions\"l\n\030EnumValueDescrip"
    "torProto\022\014\n\004name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222"
    "\n\007options\030\003 \001(\0132!.google.protobuf.EnumVa"
    "lueOptions\"\220\001\n\026ServiceDescriptorProto\022\014\n"
    "\004name\030\001 \001(\t\0226\n\006method\030\002 \003(\0132&.google.pro"
    "tobuf.MethodDescriptorProto\0220\n\007options\030\003"
    " \001(\0132\037.google.protobuf.ServiceOptions\"\177\n"
    "\025MethodDescriptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\n"
    "input_type\030\002 \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n"
    "\007options\030\004 \001(\0132\036.google.protobuf.MethodO"
    "ptions\"\351\003\n\013FileOptions\022\024\n\014java_package\030\001"
    " \001(\t\022\034\n\024java_outer_classname\030\010 \001(\t\022\"\n\023ja"
    "va_multiple_files\030\n \001(\010:\005false\022,\n\035java_g"
    "enerate_equals_and_hash\030\024 \001(\010:\005false\022F\n\014"
    "optimize_for\030\t \001(\0162).google.protobuf.Fil"
    "eOptions.OptimizeMode:\005SPEED\022\022\n\ngo_packa"
    "ge\030\013 \001(\t\022\"\n\023cc_generic_services\030\020 \001(\010:\005f"
    "alse\022$\n\025java_generic_services\030\021 \001(\010:\005fal"
    "se\022\"\n\023py_generic_services\030\022 \001(\010:\005false\022C"
    "\n\024uninterpreted_option\030\347\007 \003(\0132$.google.p"
    "rotobuf.UninterpretedOption\":\n\014OptimizeM"
    "ode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014LITE_RU"
    "NTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOptions\022&\n"
    "\027message_set_wire_format\030\001 \001(\010:\005false\022.\n"
    "\037no_standard_descriptor_accessor\030\002 \001(\010:\005"
    "false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
    "oogle.protobuf.UninterpretedOption*\t\010\350\007\020"
    "\200\200\200\200\002\"\276\002\n\014FieldOptions\022:\n\005ctype\030\001 \001(\0162#."
    "google.protobuf.FieldOptions.CType:\006STRI"
    "NG\022\016\n\006packed\030\002 \001(\010\022\023\n\004lazy\030\005 \001(\010:\005false\022"
    "\031\n\ndeprecated\030\003 \001(\010:\005false\022\034\n\024experiment"
    "al_map_key\030\t \001(\t\022\023\n\004weak\030\n \001(\010:\005false\022C\n"
    "\024uninterpreted_option\030\347\007 \003(\0132$.google.pr"
    "otobuf.UninterpretedOption\"/\n\005CType\022\n\n\006S"
    "TRING\020\000\022\010\n\004CORD\020\001\022\020\n\014STRING_PIECE\020\002*\t\010\350\007"
    "\020\200\200\200\200\002\"x\n\013EnumOptions\022\031\n\013allow_alias\030\002 \001"
    "(\010:\004true\022C\n\024uninterpreted_option\030\347\007 \003(\0132"
    "$.google.protobuf.UninterpretedOption*\t\010"
    "\350\007\020\200\200\200\200\002\"b\n\020EnumValueOptions\022C\n\024uninterp"
    "reted_option\030\347\007 \003(\0132$.google.protobuf.Un"
    "interpretedOption*\t\010\350\007\020\200\200\200\200\002\"`\n\016ServiceO"
    "ptions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
    "google.protobuf.UninterpretedOption*\t\010\350\007"
    "\020\200\200\200\200\002\"_\n\rMethodOptions\022C\n\024uninterpreted"
    "_option\030\347\007 \003(\0132$.google.protobuf.Uninter"
    "pretedOption*\t\010\350\007\020\200\200\200\200\002\"\236\002\n\023Uninterprete"
    "dOption\022;\n\004name\030\002 \003(\0132-.google.protobuf."
    "UninterpretedOption.NamePart\022\030\n\020identifi"
    "er_value\030\003 \001(\t\022\032\n\022positive_int_value\030\004 \001"
    "(\004\022\032\n\022negative_int_value\030\005 \001(\003\022\024\n\014double"
    "_value\030\006 \001(\001\022\024\n\014string_value\030\007 \001(\014\022\027\n\017ag"
    "gregate_value\030\010 \001(\t\0323\n\010NamePart\022\021\n\tname_"
    "part\030\001 \002(\t\022\024\n\014is_extension\030\002 \002(\010\"\261\001\n\016Sou"
    "rceCodeInfo\022:\n\010location\030\001 \003(\0132(.google.p"
    "rotobuf.SourceCodeInfo.Location\032c\n\010Locat"
    "ion\022\020\n\004path\030\001 \003(\005B\002\020\001\022\020\n\004span\030\002 \003(\005B\002\020\001\022"
    "\030\n\020leading_comments\030\003 \001(\t\022\031\n\021trailing_co"
    "mments\030\004 \001(\tB)\n\023com.google.protobufB\020Des"
    "criptorProtosH\001", 4135);
  ::google::protobuf::MessageFactory::InternalRegisterGeneratedFile(
    "google/protobuf/descriptor.proto", &protobuf_RegisterTypes);
  FileDescriptorSet::default_instance_ = new FileDescriptorSet();
  FileDescriptorProto::default_instance_ = new FileDescriptorProto();
  DescriptorProto::default_instance_ = new DescriptorProto();
  DescriptorProto_ExtensionRange::default_instance_ = new DescriptorProto_ExtensionRange();
  FieldDescriptorProto::default_instance_ = new FieldDescriptorProto();
  EnumDescriptorProto::default_instance_ = new EnumDescriptorProto();
  EnumValueDescriptorProto::default_instance_ = new EnumValueDescriptorProto();
  ServiceDescriptorProto::default_instance_ = new ServiceDescriptorProto();
  MethodDescriptorProto::default_instance_ = new MethodDescriptorProto();
  FileOptions::default_instance_ = new FileOptions();
  MessageOptions::default_instance_ = new MessageOptions();
  FieldOptions::default_instance_ = new FieldOptions();
  EnumOptions::default_instance_ = new EnumOptions();
  EnumValueOptions::default_instance_ = new EnumValueOptions();
  ServiceOptions::default_instance_ = new ServiceOptions();
  MethodOptions::default_instance_ = new MethodOptions();
  UninterpretedOption::default_instance_ = new UninterpretedOption();
  UninterpretedOption_NamePart::default_instance_ = new UninterpretedOption_NamePart();
  SourceCodeInfo::default_instance_ = new SourceCodeInfo();
  SourceCodeInfo_Location::default_instance_ = new SourceCodeInfo_Location();
  FileDescriptorSet::default_instance_->InitAsDefaultInstance();
  FileDescriptorProto::default_instance_->InitAsDefaultInstance();
  DescriptorProto::default_instance_->InitAsDefaultInstance();
  DescriptorProto_ExtensionRange::default_instance_->InitAsDefaultInstance();
  FieldDescriptorProto::default_instance_->InitAsDefaultInstance();
  EnumDescriptorProto::default_instance_->InitAsDefaultInstance();
  EnumValueDescriptorProto::default_instance_->InitAsDefaultInstance();
  ServiceDescriptorProto::default_instance_->InitAsDefaultInstance();
  MethodDescriptorProto::default_instance_->InitAsDefaultInstance();
  FileOptions::default_instance_->InitAsDefaultInstance();
  MessageOptions::default_instance_->InitAsDefaultInstance();
  FieldOptions::default_instance_->InitAsDefaultInstance();
  EnumOptions::default_instance_->InitAsDefaultInstance();
  EnumValueOptions::default_instance_->InitAsDefaultInstance();
  ServiceOptions::default_instance_->InitAsDefaultInstance();
  MethodOptions::default_instance_->InitAsDefaultInstance();
  UninterpretedOption::default_instance_->InitAsDefaultInstance();
  UninterpretedOption_NamePart::default_instance_->InitAsDefaultInstance();
  SourceCodeInfo::default_instance_->InitAsDefaultInstance();
  SourceCodeInfo_Location::default_instance_->InitAsDefaultInstance();
  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_2fprotobuf_2fdescriptor_2eproto);
}

// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto {
  StaticDescriptorInitializer_google_2fprotobuf_2fdescriptor_2eproto() {
    protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  }
} static_descriptor_initializer_google_2fprotobuf_2fdescriptor_2eproto_;

// ===================================================================

#ifndef _MSC_VER
const int FileDescriptorSet::kFileFieldNumber;
#endif  // !_MSC_VER

FileDescriptorSet::FileDescriptorSet()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void FileDescriptorSet::InitAsDefaultInstance() {
}

FileDescriptorSet::FileDescriptorSet(const FileDescriptorSet& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void FileDescriptorSet::SharedCtor() {
  _cached_size_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

FileDescriptorSet::~FileDescriptorSet() {
  SharedDtor();
}

void FileDescriptorSet::SharedDtor() {
  if (this != default_instance_) {
  }
}

void FileDescriptorSet::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* FileDescriptorSet::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FileDescriptorSet_descriptor_;
}

const FileDescriptorSet& FileDescriptorSet::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

FileDescriptorSet* FileDescriptorSet::default_instance_ = NULL;

FileDescriptorSet* FileDescriptorSet::New() const {
  return new FileDescriptorSet;
}

void FileDescriptorSet::Clear() {
  file_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool FileDescriptorSet::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.FileDescriptorProto file = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_file:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_file()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(10)) goto parse_file;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void FileDescriptorSet::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated .google.protobuf.FileDescriptorProto file = 1;
  for (int i = 0; i < this->file_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, this->file(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* FileDescriptorSet::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated .google.protobuf.FileDescriptorProto file = 1;
  for (int i = 0; i < this->file_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        1, this->file(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int FileDescriptorSet::ByteSize() const {
  int total_size = 0;

  // repeated .google.protobuf.FileDescriptorProto file = 1;
  total_size += 1 * this->file_size();
  for (int i = 0; i < this->file_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->file(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void FileDescriptorSet::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const FileDescriptorSet* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorSet*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void FileDescriptorSet::MergeFrom(const FileDescriptorSet& from) {
  GOOGLE_CHECK_NE(&from, this);
  file_.MergeFrom(from.file_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void FileDescriptorSet::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void FileDescriptorSet::CopyFrom(const FileDescriptorSet& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FileDescriptorSet::IsInitialized() const {

  for (int i = 0; i < file_size(); i++) {
    if (!this->file(i).IsInitialized()) return false;
  }
  return true;
}

void FileDescriptorSet::Swap(FileDescriptorSet* other) {
  if (other != this) {
    file_.Swap(&other->file_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata FileDescriptorSet::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = FileDescriptorSet_descriptor_;
  metadata.reflection = FileDescriptorSet_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int FileDescriptorProto::kNameFieldNumber;
const int FileDescriptorProto::kPackageFieldNumber;
const int FileDescriptorProto::kDependencyFieldNumber;
const int FileDescriptorProto::kPublicDependencyFieldNumber;
const int FileDescriptorProto::kWeakDependencyFieldNumber;
const int FileDescriptorProto::kMessageTypeFieldNumber;
const int FileDescriptorProto::kEnumTypeFieldNumber;
const int FileDescriptorProto::kServiceFieldNumber;
const int FileDescriptorProto::kExtensionFieldNumber;
const int FileDescriptorProto::kOptionsFieldNumber;
const int FileDescriptorProto::kSourceCodeInfoFieldNumber;
#endif  // !_MSC_VER

FileDescriptorProto::FileDescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void FileDescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::FileOptions*>(&::google::protobuf::FileOptions::default_instance());
  source_code_info_ = const_cast< ::google::protobuf::SourceCodeInfo*>(&::google::protobuf::SourceCodeInfo::default_instance());
}

FileDescriptorProto::FileDescriptorProto(const FileDescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void FileDescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  options_ = NULL;
  source_code_info_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

FileDescriptorProto::~FileDescriptorProto() {
  SharedDtor();
}

void FileDescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (package_ != &::google::protobuf::internal::kEmptyString) {
    delete package_;
  }
  if (this != default_instance_) {
    delete options_;
    delete source_code_info_;
  }
}

void FileDescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* FileDescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FileDescriptorProto_descriptor_;
}

const FileDescriptorProto& FileDescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

FileDescriptorProto* FileDescriptorProto::default_instance_ = NULL;

FileDescriptorProto* FileDescriptorProto::New() const {
  return new FileDescriptorProto;
}

void FileDescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    if (has_package()) {
      if (package_ != &::google::protobuf::internal::kEmptyString) {
        package_->clear();
      }
    }
  }
  if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) {
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
    }
    if (has_source_code_info()) {
      if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
    }
  }
  dependency_.Clear();
  public_dependency_.Clear();
  weak_dependency_.Clear();
  message_type_.Clear();
  enum_type_.Clear();
  service_.Clear();
  extension_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool FileDescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_package;
        break;
      }

      // optional string package = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_package:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->package().data(), this->package().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_dependency;
        break;
      }

      // repeated string dependency = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_dependency:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->add_dependency()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->dependency(this->dependency_size() - 1).data(),
            this->dependency(this->dependency_size() - 1).length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_dependency;
        if (input->ExpectTag(34)) goto parse_message_type;
        break;
      }

      // repeated .google.protobuf.DescriptorProto message_type = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_message_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_message_type()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(34)) goto parse_message_type;
        if (input->ExpectTag(42)) goto parse_enum_type;
        break;
      }

      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
      case 5: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_enum_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_enum_type()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(42)) goto parse_enum_type;
        if (input->ExpectTag(50)) goto parse_service;
        break;
      }

      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
      case 6: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_service:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_service()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(50)) goto parse_service;
        if (input->ExpectTag(58)) goto parse_extension;
        break;
      }

      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
      case 7: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_extension:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_extension()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(58)) goto parse_extension;
        if (input->ExpectTag(66)) goto parse_options;
        break;
      }

      // optional .google.protobuf.FileOptions options = 8;
      case 8: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(74)) goto parse_source_code_info;
        break;
      }

      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
      case 9: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_source_code_info:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_source_code_info()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(80)) goto parse_public_dependency;
        break;
      }

      // repeated int32 public_dependency = 10;
      case 10: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_public_dependency:
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 80, input, this->mutable_public_dependency())));
        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
                   == ::google::protobuf::internal::WireFormatLite::
                      WIRETYPE_LENGTH_DELIMITED) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_public_dependency())));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(80)) goto parse_public_dependency;
        if (input->ExpectTag(88)) goto parse_weak_dependency;
        break;
      }

      // repeated int32 weak_dependency = 11;
      case 11: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_weak_dependency:
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 88, input, this->mutable_weak_dependency())));
        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
                   == ::google::protobuf::internal::WireFormatLite::
                      WIRETYPE_LENGTH_DELIMITED) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_weak_dependency())));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(88)) goto parse_weak_dependency;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void FileDescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // optional string package = 2;
  if (has_package()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->package().data(), this->package().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      2, this->package(), output);
  }

  // repeated string dependency = 3;
  for (int i = 0; i < this->dependency_size(); i++) {
  ::google::protobuf::internal::WireFormat::VerifyUTF8String(
    this->dependency(i).data(), this->dependency(i).length(),
    ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      3, this->dependency(i), output);
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  for (int i = 0; i < this->message_type_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, this->message_type(i), output);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  for (int i = 0; i < this->enum_type_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, this->enum_type(i), output);
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  for (int i = 0; i < this->service_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6, this->service(i), output);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  for (int i = 0; i < this->extension_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      7, this->extension(i), output);
  }

  // optional .google.protobuf.FileOptions options = 8;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8, this->options(), output);
  }

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  if (has_source_code_info()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      9, this->source_code_info(), output);
  }

  // repeated int32 public_dependency = 10;
  for (int i = 0; i < this->public_dependency_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(
      10, this->public_dependency(i), output);
  }

  // repeated int32 weak_dependency = 11;
  for (int i = 0; i < this->weak_dependency_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(
      11, this->weak_dependency(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* FileDescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional string package = 2;
  if (has_package()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->package().data(), this->package().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->package(), target);
  }

  // repeated string dependency = 3;
  for (int i = 0; i < this->dependency_size(); i++) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->dependency(i).data(), this->dependency(i).length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target = ::google::protobuf::internal::WireFormatLite::
      WriteStringToArray(3, this->dependency(i), target);
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  for (int i = 0; i < this->message_type_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        4, this->message_type(i), target);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  for (int i = 0; i < this->enum_type_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        5, this->enum_type(i), target);
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  for (int i = 0; i < this->service_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        6, this->service(i), target);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  for (int i = 0; i < this->extension_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        7, this->extension(i), target);
  }

  // optional .google.protobuf.FileOptions options = 8;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        8, this->options(), target);
  }

  // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
  if (has_source_code_info()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        9, this->source_code_info(), target);
  }

  // repeated int32 public_dependency = 10;
  for (int i = 0; i < this->public_dependency_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32ToArray(10, this->public_dependency(i), target);
  }

  // repeated int32 weak_dependency = 11;
  for (int i = 0; i < this->weak_dependency_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32ToArray(11, this->weak_dependency(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int FileDescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional string package = 2;
    if (has_package()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->package());
    }

  }
  if (_has_bits_[9 / 32] & (0xffu << (9 % 32))) {
    // optional .google.protobuf.FileOptions options = 8;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

    // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
    if (has_source_code_info()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->source_code_info());
    }

  }
  // repeated string dependency = 3;
  total_size += 1 * this->dependency_size();
  for (int i = 0; i < this->dependency_size(); i++) {
    total_size += ::google::protobuf::internal::WireFormatLite::StringSize(
      this->dependency(i));
  }

  // repeated int32 public_dependency = 10;
  {
    int data_size = 0;
    for (int i = 0; i < this->public_dependency_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        Int32Size(this->public_dependency(i));
    }
    total_size += 1 * this->public_dependency_size() + data_size;
  }

  // repeated int32 weak_dependency = 11;
  {
    int data_size = 0;
    for (int i = 0; i < this->weak_dependency_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        Int32Size(this->weak_dependency(i));
    }
    total_size += 1 * this->weak_dependency_size() + data_size;
  }

  // repeated .google.protobuf.DescriptorProto message_type = 4;
  total_size += 1 * this->message_type_size();
  for (int i = 0; i < this->message_type_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->message_type(i));
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
  total_size += 1 * this->enum_type_size();
  for (int i = 0; i < this->enum_type_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->enum_type(i));
  }

  // repeated .google.protobuf.ServiceDescriptorProto service = 6;
  total_size += 1 * this->service_size();
  for (int i = 0; i < this->service_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->service(i));
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 7;
  total_size += 1 * this->extension_size();
  for (int i = 0; i < this->extension_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->extension(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void FileDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const FileDescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const FileDescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void FileDescriptorProto::MergeFrom(const FileDescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  dependency_.MergeFrom(from.dependency_);
  public_dependency_.MergeFrom(from.public_dependency_);
  weak_dependency_.MergeFrom(from.weak_dependency_);
  message_type_.MergeFrom(from.message_type_);
  enum_type_.MergeFrom(from.enum_type_);
  service_.MergeFrom(from.service_);
  extension_.MergeFrom(from.extension_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_package()) {
      set_package(from.package());
    }
  }
  if (from._has_bits_[9 / 32] & (0xffu << (9 % 32))) {
    if (from.has_options()) {
      mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
    }
    if (from.has_source_code_info()) {
      mutable_source_code_info()->::google::protobuf::SourceCodeInfo::MergeFrom(from.source_code_info());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void FileDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void FileDescriptorProto::CopyFrom(const FileDescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FileDescriptorProto::IsInitialized() const {

  for (int i = 0; i < message_type_size(); i++) {
    if (!this->message_type(i).IsInitialized()) return false;
  }
  for (int i = 0; i < enum_type_size(); i++) {
    if (!this->enum_type(i).IsInitialized()) return false;
  }
  for (int i = 0; i < service_size(); i++) {
    if (!this->service(i).IsInitialized()) return false;
  }
  for (int i = 0; i < extension_size(); i++) {
    if (!this->extension(i).IsInitialized()) return false;
  }
  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void FileDescriptorProto::Swap(FileDescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    std::swap(package_, other->package_);
    dependency_.Swap(&other->dependency_);
    public_dependency_.Swap(&other->public_dependency_);
    weak_dependency_.Swap(&other->weak_dependency_);
    message_type_.Swap(&other->message_type_);
    enum_type_.Swap(&other->enum_type_);
    service_.Swap(&other->service_);
    extension_.Swap(&other->extension_);
    std::swap(options_, other->options_);
    std::swap(source_code_info_, other->source_code_info_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata FileDescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = FileDescriptorProto_descriptor_;
  metadata.reflection = FileDescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int DescriptorProto_ExtensionRange::kStartFieldNumber;
const int DescriptorProto_ExtensionRange::kEndFieldNumber;
#endif  // !_MSC_VER

DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void DescriptorProto_ExtensionRange::InitAsDefaultInstance() {
}

DescriptorProto_ExtensionRange::DescriptorProto_ExtensionRange(const DescriptorProto_ExtensionRange& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void DescriptorProto_ExtensionRange::SharedCtor() {
  _cached_size_ = 0;
  start_ = 0;
  end_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

DescriptorProto_ExtensionRange::~DescriptorProto_ExtensionRange() {
  SharedDtor();
}

void DescriptorProto_ExtensionRange::SharedDtor() {
  if (this != default_instance_) {
  }
}

void DescriptorProto_ExtensionRange::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* DescriptorProto_ExtensionRange::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return DescriptorProto_ExtensionRange_descriptor_;
}

const DescriptorProto_ExtensionRange& DescriptorProto_ExtensionRange::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::default_instance_ = NULL;

DescriptorProto_ExtensionRange* DescriptorProto_ExtensionRange::New() const {
  return new DescriptorProto_ExtensionRange;
}

void DescriptorProto_ExtensionRange::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    start_ = 0;
    end_ = 0;
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool DescriptorProto_ExtensionRange::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional int32 start = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &start_)));
          set_has_start();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(16)) goto parse_end;
        break;
      }

      // optional int32 end = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_end:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &end_)));
          set_has_end();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void DescriptorProto_ExtensionRange::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional int32 start = 1;
  if (has_start()) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(1, this->start(), output);
  }

  // optional int32 end = 2;
  if (has_end()) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->end(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* DescriptorProto_ExtensionRange::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional int32 start = 1;
  if (has_start()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(1, this->start(), target);
  }

  // optional int32 end = 2;
  if (has_end()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->end(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int DescriptorProto_ExtensionRange::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional int32 start = 1;
    if (has_start()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->start());
    }

    // optional int32 end = 2;
    if (has_end()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->end());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void DescriptorProto_ExtensionRange::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const DescriptorProto_ExtensionRange* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto_ExtensionRange*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void DescriptorProto_ExtensionRange::MergeFrom(const DescriptorProto_ExtensionRange& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_start()) {
      set_start(from.start());
    }
    if (from.has_end()) {
      set_end(from.end());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void DescriptorProto_ExtensionRange::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void DescriptorProto_ExtensionRange::CopyFrom(const DescriptorProto_ExtensionRange& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool DescriptorProto_ExtensionRange::IsInitialized() const {

  return true;
}

void DescriptorProto_ExtensionRange::Swap(DescriptorProto_ExtensionRange* other) {
  if (other != this) {
    std::swap(start_, other->start_);
    std::swap(end_, other->end_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata DescriptorProto_ExtensionRange::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = DescriptorProto_ExtensionRange_descriptor_;
  metadata.reflection = DescriptorProto_ExtensionRange_reflection_;
  return metadata;
}


// -------------------------------------------------------------------

#ifndef _MSC_VER
const int DescriptorProto::kNameFieldNumber;
const int DescriptorProto::kFieldFieldNumber;
const int DescriptorProto::kExtensionFieldNumber;
const int DescriptorProto::kNestedTypeFieldNumber;
const int DescriptorProto::kEnumTypeFieldNumber;
const int DescriptorProto::kExtensionRangeFieldNumber;
const int DescriptorProto::kOptionsFieldNumber;
#endif  // !_MSC_VER

DescriptorProto::DescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void DescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::MessageOptions*>(&::google::protobuf::MessageOptions::default_instance());
}

DescriptorProto::DescriptorProto(const DescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void DescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  options_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

DescriptorProto::~DescriptorProto() {
  SharedDtor();
}

void DescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (this != default_instance_) {
    delete options_;
  }
}

void DescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* DescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return DescriptorProto_descriptor_;
}

const DescriptorProto& DescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

DescriptorProto* DescriptorProto::default_instance_ = NULL;

DescriptorProto* DescriptorProto::New() const {
  return new DescriptorProto;
}

void DescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::MessageOptions::Clear();
    }
  }
  field_.Clear();
  extension_.Clear();
  nested_type_.Clear();
  enum_type_.Clear();
  extension_range_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool DescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_field;
        break;
      }

      // repeated .google.protobuf.FieldDescriptorProto field = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_field:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_field()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_field;
        if (input->ExpectTag(26)) goto parse_nested_type;
        break;
      }

      // repeated .google.protobuf.DescriptorProto nested_type = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_nested_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_nested_type()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_nested_type;
        if (input->ExpectTag(34)) goto parse_enum_type;
        break;
      }

      // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_enum_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_enum_type()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(34)) goto parse_enum_type;
        if (input->ExpectTag(42)) goto parse_extension_range;
        break;
      }

      // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
      case 5: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_extension_range:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_extension_range()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(42)) goto parse_extension_range;
        if (input->ExpectTag(50)) goto parse_extension;
        break;
      }

      // repeated .google.protobuf.FieldDescriptorProto extension = 6;
      case 6: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_extension:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_extension()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(50)) goto parse_extension;
        if (input->ExpectTag(58)) goto parse_options;
        break;
      }

      // optional .google.protobuf.MessageOptions options = 7;
      case 7: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void DescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  for (int i = 0; i < this->field_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->field(i), output);
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  for (int i = 0; i < this->nested_type_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->nested_type(i), output);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  for (int i = 0; i < this->enum_type_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, this->enum_type(i), output);
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  for (int i = 0; i < this->extension_range_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      5, this->extension_range(i), output);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  for (int i = 0; i < this->extension_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      6, this->extension(i), output);
  }

  // optional .google.protobuf.MessageOptions options = 7;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      7, this->options(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* DescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  for (int i = 0; i < this->field_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        2, this->field(i), target);
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  for (int i = 0; i < this->nested_type_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        3, this->nested_type(i), target);
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  for (int i = 0; i < this->enum_type_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        4, this->enum_type(i), target);
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  for (int i = 0; i < this->extension_range_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        5, this->extension_range(i), target);
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  for (int i = 0; i < this->extension_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        6, this->extension(i), target);
  }

  // optional .google.protobuf.MessageOptions options = 7;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        7, this->options(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int DescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.MessageOptions options = 7;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

  }
  // repeated .google.protobuf.FieldDescriptorProto field = 2;
  total_size += 1 * this->field_size();
  for (int i = 0; i < this->field_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->field(i));
  }

  // repeated .google.protobuf.FieldDescriptorProto extension = 6;
  total_size += 1 * this->extension_size();
  for (int i = 0; i < this->extension_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->extension(i));
  }

  // repeated .google.protobuf.DescriptorProto nested_type = 3;
  total_size += 1 * this->nested_type_size();
  for (int i = 0; i < this->nested_type_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->nested_type(i));
  }

  // repeated .google.protobuf.EnumDescriptorProto enum_type = 4;
  total_size += 1 * this->enum_type_size();
  for (int i = 0; i < this->enum_type_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->enum_type(i));
  }

  // repeated .google.protobuf.DescriptorProto.ExtensionRange extension_range = 5;
  total_size += 1 * this->extension_range_size();
  for (int i = 0; i < this->extension_range_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->extension_range(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void DescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const DescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const DescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void DescriptorProto::MergeFrom(const DescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  field_.MergeFrom(from.field_);
  extension_.MergeFrom(from.extension_);
  nested_type_.MergeFrom(from.nested_type_);
  enum_type_.MergeFrom(from.enum_type_);
  extension_range_.MergeFrom(from.extension_range_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_options()) {
      mutable_options()->::google::protobuf::MessageOptions::MergeFrom(from.options());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void DescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void DescriptorProto::CopyFrom(const DescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool DescriptorProto::IsInitialized() const {

  for (int i = 0; i < field_size(); i++) {
    if (!this->field(i).IsInitialized()) return false;
  }
  for (int i = 0; i < extension_size(); i++) {
    if (!this->extension(i).IsInitialized()) return false;
  }
  for (int i = 0; i < nested_type_size(); i++) {
    if (!this->nested_type(i).IsInitialized()) return false;
  }
  for (int i = 0; i < enum_type_size(); i++) {
    if (!this->enum_type(i).IsInitialized()) return false;
  }
  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void DescriptorProto::Swap(DescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    field_.Swap(&other->field_);
    extension_.Swap(&other->extension_);
    nested_type_.Swap(&other->nested_type_);
    enum_type_.Swap(&other->enum_type_);
    extension_range_.Swap(&other->extension_range_);
    std::swap(options_, other->options_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata DescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = DescriptorProto_descriptor_;
  metadata.reflection = DescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Type_descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FieldDescriptorProto_Type_descriptor_;
}
bool FieldDescriptorProto_Type_IsValid(int value) {
  switch(value) {
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
    case 9:
    case 10:
    case 11:
    case 12:
    case 13:
    case 14:
    case 15:
    case 16:
    case 17:
    case 18:
      return true;
    default:
      return false;
  }
}

#ifndef _MSC_VER
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_DOUBLE;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FLOAT;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_INT32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_FIXED32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BOOL;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_STRING;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_GROUP;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_MESSAGE;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_BYTES;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_UINT32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_ENUM;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SFIXED64;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT32;
const FieldDescriptorProto_Type FieldDescriptorProto::TYPE_SINT64;
const FieldDescriptorProto_Type FieldDescriptorProto::Type_MIN;
const FieldDescriptorProto_Type FieldDescriptorProto::Type_MAX;
const int FieldDescriptorProto::Type_ARRAYSIZE;
#endif  // _MSC_VER
const ::google::protobuf::EnumDescriptor* FieldDescriptorProto_Label_descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FieldDescriptorProto_Label_descriptor_;
}
bool FieldDescriptorProto_Label_IsValid(int value) {
  switch(value) {
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#ifndef _MSC_VER
const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_OPTIONAL;
const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REQUIRED;
const FieldDescriptorProto_Label FieldDescriptorProto::LABEL_REPEATED;
const FieldDescriptorProto_Label FieldDescriptorProto::Label_MIN;
const FieldDescriptorProto_Label FieldDescriptorProto::Label_MAX;
const int FieldDescriptorProto::Label_ARRAYSIZE;
#endif  // _MSC_VER
#ifndef _MSC_VER
const int FieldDescriptorProto::kNameFieldNumber;
const int FieldDescriptorProto::kNumberFieldNumber;
const int FieldDescriptorProto::kLabelFieldNumber;
const int FieldDescriptorProto::kTypeFieldNumber;
const int FieldDescriptorProto::kTypeNameFieldNumber;
const int FieldDescriptorProto::kExtendeeFieldNumber;
const int FieldDescriptorProto::kDefaultValueFieldNumber;
const int FieldDescriptorProto::kOptionsFieldNumber;
#endif  // !_MSC_VER

FieldDescriptorProto::FieldDescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void FieldDescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::FieldOptions*>(&::google::protobuf::FieldOptions::default_instance());
}

FieldDescriptorProto::FieldDescriptorProto(const FieldDescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void FieldDescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  number_ = 0;
  label_ = 1;
  type_ = 1;
  type_name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  extendee_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  default_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  options_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

FieldDescriptorProto::~FieldDescriptorProto() {
  SharedDtor();
}

void FieldDescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (type_name_ != &::google::protobuf::internal::kEmptyString) {
    delete type_name_;
  }
  if (extendee_ != &::google::protobuf::internal::kEmptyString) {
    delete extendee_;
  }
  if (default_value_ != &::google::protobuf::internal::kEmptyString) {
    delete default_value_;
  }
  if (this != default_instance_) {
    delete options_;
  }
}

void FieldDescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* FieldDescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FieldDescriptorProto_descriptor_;
}

const FieldDescriptorProto& FieldDescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

FieldDescriptorProto* FieldDescriptorProto::default_instance_ = NULL;

FieldDescriptorProto* FieldDescriptorProto::New() const {
  return new FieldDescriptorProto;
}

void FieldDescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    number_ = 0;
    label_ = 1;
    type_ = 1;
    if (has_type_name()) {
      if (type_name_ != &::google::protobuf::internal::kEmptyString) {
        type_name_->clear();
      }
    }
    if (has_extendee()) {
      if (extendee_ != &::google::protobuf::internal::kEmptyString) {
        extendee_->clear();
      }
    }
    if (has_default_value()) {
      if (default_value_ != &::google::protobuf::internal::kEmptyString) {
        default_value_->clear();
      }
    }
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::FieldOptions::Clear();
    }
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool FieldDescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_extendee;
        break;
      }

      // optional string extendee = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_extendee:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_extendee()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->extendee().data(), this->extendee().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(24)) goto parse_number;
        break;
      }

      // optional int32 number = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_number:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &number_)));
          set_has_number();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(32)) goto parse_label;
        break;
      }

      // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_label:
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldDescriptorProto_Label_IsValid(value)) {
            set_label(static_cast< ::google::protobuf::FieldDescriptorProto_Label >(value));
          } else {
            mutable_unknown_fields()->AddVarint(4, value);
          }
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(40)) goto parse_type;
        break;
      }

      // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
      case 5: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_type:
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldDescriptorProto_Type_IsValid(value)) {
            set_type(static_cast< ::google::protobuf::FieldDescriptorProto_Type >(value));
          } else {
            mutable_unknown_fields()->AddVarint(5, value);
          }
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(50)) goto parse_type_name;
        break;
      }

      // optional string type_name = 6;
      case 6: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_type_name:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_type_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->type_name().data(), this->type_name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(58)) goto parse_default_value;
        break;
      }

      // optional string default_value = 7;
      case 7: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_default_value:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_default_value()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->default_value().data(), this->default_value().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(66)) goto parse_options;
        break;
      }

      // optional .google.protobuf.FieldOptions options = 8;
      case 8: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void FieldDescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // optional string extendee = 2;
  if (has_extendee()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->extendee().data(), this->extendee().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      2, this->extendee(), output);
  }

  // optional int32 number = 3;
  if (has_number()) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(3, this->number(), output);
  }

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  if (has_label()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      4, this->label(), output);
  }

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  if (has_type()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      5, this->type(), output);
  }

  // optional string type_name = 6;
  if (has_type_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->type_name().data(), this->type_name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      6, this->type_name(), output);
  }

  // optional string default_value = 7;
  if (has_default_value()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->default_value().data(), this->default_value().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      7, this->default_value(), output);
  }

  // optional .google.protobuf.FieldOptions options = 8;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      8, this->options(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* FieldDescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional string extendee = 2;
  if (has_extendee()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->extendee().data(), this->extendee().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->extendee(), target);
  }

  // optional int32 number = 3;
  if (has_number()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(3, this->number(), target);
  }

  // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
  if (has_label()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      4, this->label(), target);
  }

  // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
  if (has_type()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      5, this->type(), target);
  }

  // optional string type_name = 6;
  if (has_type_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->type_name().data(), this->type_name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        6, this->type_name(), target);
  }

  // optional string default_value = 7;
  if (has_default_value()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->default_value().data(), this->default_value().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        7, this->default_value(), target);
  }

  // optional .google.protobuf.FieldOptions options = 8;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        8, this->options(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int FieldDescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional int32 number = 3;
    if (has_number()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->number());
    }

    // optional .google.protobuf.FieldDescriptorProto.Label label = 4;
    if (has_label()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->label());
    }

    // optional .google.protobuf.FieldDescriptorProto.Type type = 5;
    if (has_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->type());
    }

    // optional string type_name = 6;
    if (has_type_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->type_name());
    }

    // optional string extendee = 2;
    if (has_extendee()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->extendee());
    }

    // optional string default_value = 7;
    if (has_default_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->default_value());
    }

    // optional .google.protobuf.FieldOptions options = 8;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void FieldDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const FieldDescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const FieldDescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void FieldDescriptorProto::MergeFrom(const FieldDescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_number()) {
      set_number(from.number());
    }
    if (from.has_label()) {
      set_label(from.label());
    }
    if (from.has_type()) {
      set_type(from.type());
    }
    if (from.has_type_name()) {
      set_type_name(from.type_name());
    }
    if (from.has_extendee()) {
      set_extendee(from.extendee());
    }
    if (from.has_default_value()) {
      set_default_value(from.default_value());
    }
    if (from.has_options()) {
      mutable_options()->::google::protobuf::FieldOptions::MergeFrom(from.options());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void FieldDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void FieldDescriptorProto::CopyFrom(const FieldDescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FieldDescriptorProto::IsInitialized() const {

  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void FieldDescriptorProto::Swap(FieldDescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    std::swap(number_, other->number_);
    std::swap(label_, other->label_);
    std::swap(type_, other->type_);
    std::swap(type_name_, other->type_name_);
    std::swap(extendee_, other->extendee_);
    std::swap(default_value_, other->default_value_);
    std::swap(options_, other->options_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata FieldDescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = FieldDescriptorProto_descriptor_;
  metadata.reflection = FieldDescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int EnumDescriptorProto::kNameFieldNumber;
const int EnumDescriptorProto::kValueFieldNumber;
const int EnumDescriptorProto::kOptionsFieldNumber;
#endif  // !_MSC_VER

EnumDescriptorProto::EnumDescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void EnumDescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::EnumOptions*>(&::google::protobuf::EnumOptions::default_instance());
}

EnumDescriptorProto::EnumDescriptorProto(const EnumDescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void EnumDescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  options_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

EnumDescriptorProto::~EnumDescriptorProto() {
  SharedDtor();
}

void EnumDescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (this != default_instance_) {
    delete options_;
  }
}

void EnumDescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* EnumDescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return EnumDescriptorProto_descriptor_;
}

const EnumDescriptorProto& EnumDescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

EnumDescriptorProto* EnumDescriptorProto::default_instance_ = NULL;

EnumDescriptorProto* EnumDescriptorProto::New() const {
  return new EnumDescriptorProto;
}

void EnumDescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::EnumOptions::Clear();
    }
  }
  value_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool EnumDescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_value;
        break;
      }

      // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_value:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_value()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_value;
        if (input->ExpectTag(26)) goto parse_options;
        break;
      }

      // optional .google.protobuf.EnumOptions options = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void EnumDescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  for (int i = 0; i < this->value_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->value(i), output);
  }

  // optional .google.protobuf.EnumOptions options = 3;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->options(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* EnumDescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  for (int i = 0; i < this->value_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        2, this->value(i), target);
  }

  // optional .google.protobuf.EnumOptions options = 3;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        3, this->options(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int EnumDescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.EnumOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

  }
  // repeated .google.protobuf.EnumValueDescriptorProto value = 2;
  total_size += 1 * this->value_size();
  for (int i = 0; i < this->value_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->value(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void EnumDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const EnumDescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const EnumDescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void EnumDescriptorProto::MergeFrom(const EnumDescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  value_.MergeFrom(from.value_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_options()) {
      mutable_options()->::google::protobuf::EnumOptions::MergeFrom(from.options());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void EnumDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EnumDescriptorProto::CopyFrom(const EnumDescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumDescriptorProto::IsInitialized() const {

  for (int i = 0; i < value_size(); i++) {
    if (!this->value(i).IsInitialized()) return false;
  }
  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void EnumDescriptorProto::Swap(EnumDescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    value_.Swap(&other->value_);
    std::swap(options_, other->options_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata EnumDescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = EnumDescriptorProto_descriptor_;
  metadata.reflection = EnumDescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int EnumValueDescriptorProto::kNameFieldNumber;
const int EnumValueDescriptorProto::kNumberFieldNumber;
const int EnumValueDescriptorProto::kOptionsFieldNumber;
#endif  // !_MSC_VER

EnumValueDescriptorProto::EnumValueDescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void EnumValueDescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::EnumValueOptions*>(&::google::protobuf::EnumValueOptions::default_instance());
}

EnumValueDescriptorProto::EnumValueDescriptorProto(const EnumValueDescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void EnumValueDescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  number_ = 0;
  options_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

EnumValueDescriptorProto::~EnumValueDescriptorProto() {
  SharedDtor();
}

void EnumValueDescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (this != default_instance_) {
    delete options_;
  }
}

void EnumValueDescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* EnumValueDescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return EnumValueDescriptorProto_descriptor_;
}

const EnumValueDescriptorProto& EnumValueDescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

EnumValueDescriptorProto* EnumValueDescriptorProto::default_instance_ = NULL;

EnumValueDescriptorProto* EnumValueDescriptorProto::New() const {
  return new EnumValueDescriptorProto;
}

void EnumValueDescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    number_ = 0;
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::EnumValueOptions::Clear();
    }
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool EnumValueDescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(16)) goto parse_number;
        break;
      }

      // optional int32 number = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_number:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, &number_)));
          set_has_number();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_options;
        break;
      }

      // optional .google.protobuf.EnumValueOptions options = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void EnumValueDescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // optional int32 number = 2;
  if (has_number()) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32(2, this->number(), output);
  }

  // optional .google.protobuf.EnumValueOptions options = 3;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->options(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* EnumValueDescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional int32 number = 2;
  if (has_number()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt32ToArray(2, this->number(), target);
  }

  // optional .google.protobuf.EnumValueOptions options = 3;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        3, this->options(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int EnumValueDescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional int32 number = 2;
    if (has_number()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(
          this->number());
    }

    // optional .google.protobuf.EnumValueOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void EnumValueDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const EnumValueDescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueDescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void EnumValueDescriptorProto::MergeFrom(const EnumValueDescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_number()) {
      set_number(from.number());
    }
    if (from.has_options()) {
      mutable_options()->::google::protobuf::EnumValueOptions::MergeFrom(from.options());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void EnumValueDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EnumValueDescriptorProto::CopyFrom(const EnumValueDescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumValueDescriptorProto::IsInitialized() const {

  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void EnumValueDescriptorProto::Swap(EnumValueDescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    std::swap(number_, other->number_);
    std::swap(options_, other->options_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata EnumValueDescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = EnumValueDescriptorProto_descriptor_;
  metadata.reflection = EnumValueDescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int ServiceDescriptorProto::kNameFieldNumber;
const int ServiceDescriptorProto::kMethodFieldNumber;
const int ServiceDescriptorProto::kOptionsFieldNumber;
#endif  // !_MSC_VER

ServiceDescriptorProto::ServiceDescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void ServiceDescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::ServiceOptions*>(&::google::protobuf::ServiceOptions::default_instance());
}

ServiceDescriptorProto::ServiceDescriptorProto(const ServiceDescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void ServiceDescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  options_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

ServiceDescriptorProto::~ServiceDescriptorProto() {
  SharedDtor();
}

void ServiceDescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (this != default_instance_) {
    delete options_;
  }
}

void ServiceDescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* ServiceDescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return ServiceDescriptorProto_descriptor_;
}

const ServiceDescriptorProto& ServiceDescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

ServiceDescriptorProto* ServiceDescriptorProto::default_instance_ = NULL;

ServiceDescriptorProto* ServiceDescriptorProto::New() const {
  return new ServiceDescriptorProto;
}

void ServiceDescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::ServiceOptions::Clear();
    }
  }
  method_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool ServiceDescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_method;
        break;
      }

      // repeated .google.protobuf.MethodDescriptorProto method = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_method:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_method()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_method;
        if (input->ExpectTag(26)) goto parse_options;
        break;
      }

      // optional .google.protobuf.ServiceOptions options = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void ServiceDescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  for (int i = 0; i < this->method_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->method(i), output);
  }

  // optional .google.protobuf.ServiceOptions options = 3;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      3, this->options(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* ServiceDescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  for (int i = 0; i < this->method_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        2, this->method(i), target);
  }

  // optional .google.protobuf.ServiceOptions options = 3;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        3, this->options(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int ServiceDescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional .google.protobuf.ServiceOptions options = 3;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

  }
  // repeated .google.protobuf.MethodDescriptorProto method = 2;
  total_size += 1 * this->method_size();
  for (int i = 0; i < this->method_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->method(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void ServiceDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const ServiceDescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const ServiceDescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void ServiceDescriptorProto::MergeFrom(const ServiceDescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  method_.MergeFrom(from.method_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_options()) {
      mutable_options()->::google::protobuf::ServiceOptions::MergeFrom(from.options());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void ServiceDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void ServiceDescriptorProto::CopyFrom(const ServiceDescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ServiceDescriptorProto::IsInitialized() const {

  for (int i = 0; i < method_size(); i++) {
    if (!this->method(i).IsInitialized()) return false;
  }
  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void ServiceDescriptorProto::Swap(ServiceDescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    method_.Swap(&other->method_);
    std::swap(options_, other->options_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata ServiceDescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = ServiceDescriptorProto_descriptor_;
  metadata.reflection = ServiceDescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int MethodDescriptorProto::kNameFieldNumber;
const int MethodDescriptorProto::kInputTypeFieldNumber;
const int MethodDescriptorProto::kOutputTypeFieldNumber;
const int MethodDescriptorProto::kOptionsFieldNumber;
#endif  // !_MSC_VER

MethodDescriptorProto::MethodDescriptorProto()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void MethodDescriptorProto::InitAsDefaultInstance() {
  options_ = const_cast< ::google::protobuf::MethodOptions*>(&::google::protobuf::MethodOptions::default_instance());
}

MethodDescriptorProto::MethodDescriptorProto(const MethodDescriptorProto& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void MethodDescriptorProto::SharedCtor() {
  _cached_size_ = 0;
  name_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  input_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  output_type_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  options_ = NULL;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MethodDescriptorProto::~MethodDescriptorProto() {
  SharedDtor();
}

void MethodDescriptorProto::SharedDtor() {
  if (name_ != &::google::protobuf::internal::kEmptyString) {
    delete name_;
  }
  if (input_type_ != &::google::protobuf::internal::kEmptyString) {
    delete input_type_;
  }
  if (output_type_ != &::google::protobuf::internal::kEmptyString) {
    delete output_type_;
  }
  if (this != default_instance_) {
    delete options_;
  }
}

void MethodDescriptorProto::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MethodDescriptorProto::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MethodDescriptorProto_descriptor_;
}

const MethodDescriptorProto& MethodDescriptorProto::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

MethodDescriptorProto* MethodDescriptorProto::default_instance_ = NULL;

MethodDescriptorProto* MethodDescriptorProto::New() const {
  return new MethodDescriptorProto;
}

void MethodDescriptorProto::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name()) {
      if (name_ != &::google::protobuf::internal::kEmptyString) {
        name_->clear();
      }
    }
    if (has_input_type()) {
      if (input_type_ != &::google::protobuf::internal::kEmptyString) {
        input_type_->clear();
      }
    }
    if (has_output_type()) {
      if (output_type_ != &::google::protobuf::internal::kEmptyString) {
        output_type_->clear();
      }
    }
    if (has_options()) {
      if (options_ != NULL) options_->::google::protobuf::MethodOptions::Clear();
    }
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MethodDescriptorProto::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string name = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name().data(), this->name().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_input_type;
        break;
      }

      // optional string input_type = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_input_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_input_type()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->input_type().data(), this->input_type().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_output_type;
        break;
      }

      // optional string output_type = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_output_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_output_type()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->output_type().data(), this->output_type().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(34)) goto parse_options;
        break;
      }

      // optional .google.protobuf.MethodOptions options = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void MethodDescriptorProto::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name(), output);
  }

  // optional string input_type = 2;
  if (has_input_type()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->input_type().data(), this->input_type().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      2, this->input_type(), output);
  }

  // optional string output_type = 3;
  if (has_output_type()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->output_type().data(), this->output_type().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      3, this->output_type(), output);
  }

  // optional .google.protobuf.MethodOptions options = 4;
  if (has_options()) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      4, this->options(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* MethodDescriptorProto::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string name = 1;
  if (has_name()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name().data(), this->name().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name(), target);
  }

  // optional string input_type = 2;
  if (has_input_type()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->input_type().data(), this->input_type().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        2, this->input_type(), target);
  }

  // optional string output_type = 3;
  if (has_output_type()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->output_type().data(), this->output_type().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->output_type(), target);
  }

  // optional .google.protobuf.MethodOptions options = 4;
  if (has_options()) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        4, this->options(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int MethodDescriptorProto::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string name = 1;
    if (has_name()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name());
    }

    // optional string input_type = 2;
    if (has_input_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->input_type());
    }

    // optional string output_type = 3;
    if (has_output_type()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->output_type());
    }

    // optional .google.protobuf.MethodOptions options = 4;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MethodDescriptorProto::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MethodDescriptorProto* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MethodDescriptorProto*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MethodDescriptorProto::MergeFrom(const MethodDescriptorProto& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name()) {
      set_name(from.name());
    }
    if (from.has_input_type()) {
      set_input_type(from.input_type());
    }
    if (from.has_output_type()) {
      set_output_type(from.output_type());
    }
    if (from.has_options()) {
      mutable_options()->::google::protobuf::MethodOptions::MergeFrom(from.options());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MethodDescriptorProto::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MethodDescriptorProto::CopyFrom(const MethodDescriptorProto& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MethodDescriptorProto::IsInitialized() const {

  if (has_options()) {
    if (!this->options().IsInitialized()) return false;
  }
  return true;
}

void MethodDescriptorProto::Swap(MethodDescriptorProto* other) {
  if (other != this) {
    std::swap(name_, other->name_);
    std::swap(input_type_, other->input_type_);
    std::swap(output_type_, other->output_type_);
    std::swap(options_, other->options_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata MethodDescriptorProto::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MethodDescriptorProto_descriptor_;
  metadata.reflection = MethodDescriptorProto_reflection_;
  return metadata;
}


// ===================================================================

const ::google::protobuf::EnumDescriptor* FileOptions_OptimizeMode_descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FileOptions_OptimizeMode_descriptor_;
}
bool FileOptions_OptimizeMode_IsValid(int value) {
  switch(value) {
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#ifndef _MSC_VER
const FileOptions_OptimizeMode FileOptions::SPEED;
const FileOptions_OptimizeMode FileOptions::CODE_SIZE;
const FileOptions_OptimizeMode FileOptions::LITE_RUNTIME;
const FileOptions_OptimizeMode FileOptions::OptimizeMode_MIN;
const FileOptions_OptimizeMode FileOptions::OptimizeMode_MAX;
const int FileOptions::OptimizeMode_ARRAYSIZE;
#endif  // _MSC_VER
#ifndef _MSC_VER
const int FileOptions::kJavaPackageFieldNumber;
const int FileOptions::kJavaOuterClassnameFieldNumber;
const int FileOptions::kJavaMultipleFilesFieldNumber;
const int FileOptions::kJavaGenerateEqualsAndHashFieldNumber;
const int FileOptions::kOptimizeForFieldNumber;
const int FileOptions::kGoPackageFieldNumber;
const int FileOptions::kCcGenericServicesFieldNumber;
const int FileOptions::kJavaGenericServicesFieldNumber;
const int FileOptions::kPyGenericServicesFieldNumber;
const int FileOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

FileOptions::FileOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void FileOptions::InitAsDefaultInstance() {
}

FileOptions::FileOptions(const FileOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void FileOptions::SharedCtor() {
  _cached_size_ = 0;
  java_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  java_outer_classname_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  java_multiple_files_ = false;
  java_generate_equals_and_hash_ = false;
  optimize_for_ = 1;
  go_package_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  cc_generic_services_ = false;
  java_generic_services_ = false;
  py_generic_services_ = false;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

FileOptions::~FileOptions() {
  SharedDtor();
}

void FileOptions::SharedDtor() {
  if (java_package_ != &::google::protobuf::internal::kEmptyString) {
    delete java_package_;
  }
  if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
    delete java_outer_classname_;
  }
  if (go_package_ != &::google::protobuf::internal::kEmptyString) {
    delete go_package_;
  }
  if (this != default_instance_) {
  }
}

void FileOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* FileOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FileOptions_descriptor_;
}

const FileOptions& FileOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

FileOptions* FileOptions::default_instance_ = NULL;

FileOptions* FileOptions::New() const {
  return new FileOptions;
}

void FileOptions::Clear() {
  _extensions_.Clear();
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_java_package()) {
      if (java_package_ != &::google::protobuf::internal::kEmptyString) {
        java_package_->clear();
      }
    }
    if (has_java_outer_classname()) {
      if (java_outer_classname_ != &::google::protobuf::internal::kEmptyString) {
        java_outer_classname_->clear();
      }
    }
    java_multiple_files_ = false;
    java_generate_equals_and_hash_ = false;
    optimize_for_ = 1;
    if (has_go_package()) {
      if (go_package_ != &::google::protobuf::internal::kEmptyString) {
        go_package_->clear();
      }
    }
    cc_generic_services_ = false;
    java_generic_services_ = false;
  }
  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    py_generic_services_ = false;
  }
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool FileOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string java_package = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_java_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->java_package().data(), this->java_package().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(66)) goto parse_java_outer_classname;
        break;
      }

      // optional string java_outer_classname = 8;
      case 8: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_java_outer_classname:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_java_outer_classname()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->java_outer_classname().data(), this->java_outer_classname().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(72)) goto parse_optimize_for;
        break;
      }

      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
      case 9: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_optimize_for:
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
            set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
          } else {
            mutable_unknown_fields()->AddVarint(9, value);
          }
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(80)) goto parse_java_multiple_files;
        break;
      }

      // optional bool java_multiple_files = 10 [default = false];
      case 10: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_java_multiple_files:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_multiple_files_)));
          set_has_java_multiple_files();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(90)) goto parse_go_package;
        break;
      }

      // optional string go_package = 11;
      case 11: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_go_package:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_go_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->go_package().data(), this->go_package().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(128)) goto parse_cc_generic_services;
        break;
      }

      // optional bool cc_generic_services = 16 [default = false];
      case 16: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_cc_generic_services:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &cc_generic_services_)));
          set_has_cc_generic_services();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(136)) goto parse_java_generic_services;
        break;
      }

      // optional bool java_generic_services = 17 [default = false];
      case 17: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_java_generic_services:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_generic_services_)));
          set_has_java_generic_services();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(144)) goto parse_py_generic_services;
        break;
      }

      // optional bool py_generic_services = 18 [default = false];
      case 18: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_py_generic_services:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &py_generic_services_)));
          set_has_py_generic_services();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(160)) goto parse_java_generate_equals_and_hash;
        break;
      }

      // optional bool java_generate_equals_and_hash = 20 [default = false];
      case 20: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_java_generate_equals_and_hash:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_generate_equals_and_hash_)));
          set_has_java_generate_equals_and_hash();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void FileOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional string java_package = 1;
  if (has_java_package()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->java_package().data(), this->java_package().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->java_package(), output);
  }

  // optional string java_outer_classname = 8;
  if (has_java_outer_classname()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->java_outer_classname().data(), this->java_outer_classname().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      8, this->java_outer_classname(), output);
  }

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  if (has_optimize_for()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      9, this->optimize_for(), output);
  }

  // optional bool java_multiple_files = 10 [default = false];
  if (has_java_multiple_files()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->java_multiple_files(), output);
  }

  // optional string go_package = 11;
  if (has_go_package()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->go_package().data(), this->go_package().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      11, this->go_package(), output);
  }

  // optional bool cc_generic_services = 16 [default = false];
  if (has_cc_generic_services()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(16, this->cc_generic_services(), output);
  }

  // optional bool java_generic_services = 17 [default = false];
  if (has_java_generic_services()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(17, this->java_generic_services(), output);
  }

  // optional bool py_generic_services = 18 [default = false];
  if (has_py_generic_services()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(18, this->py_generic_services(), output);
  }

  // optional bool java_generate_equals_and_hash = 20 [default = false];
  if (has_java_generate_equals_and_hash()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(20, this->java_generate_equals_and_hash(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* FileOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional string java_package = 1;
  if (has_java_package()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->java_package().data(), this->java_package().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->java_package(), target);
  }

  // optional string java_outer_classname = 8;
  if (has_java_outer_classname()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->java_outer_classname().data(), this->java_outer_classname().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        8, this->java_outer_classname(), target);
  }

  // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
  if (has_optimize_for()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      9, this->optimize_for(), target);
  }

  // optional bool java_multiple_files = 10 [default = false];
  if (has_java_multiple_files()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->java_multiple_files(), target);
  }

  // optional string go_package = 11;
  if (has_go_package()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->go_package().data(), this->go_package().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        11, this->go_package(), target);
  }

  // optional bool cc_generic_services = 16 [default = false];
  if (has_cc_generic_services()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(16, this->cc_generic_services(), target);
  }

  // optional bool java_generic_services = 17 [default = false];
  if (has_java_generic_services()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(17, this->java_generic_services(), target);
  }

  // optional bool py_generic_services = 18 [default = false];
  if (has_py_generic_services()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(18, this->py_generic_services(), target);
  }

  // optional bool java_generate_equals_and_hash = 20 [default = false];
  if (has_java_generate_equals_and_hash()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(20, this->java_generate_equals_and_hash(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int FileOptions::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional string java_package = 1;
    if (has_java_package()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->java_package());
    }

    // optional string java_outer_classname = 8;
    if (has_java_outer_classname()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->java_outer_classname());
    }

    // optional bool java_multiple_files = 10 [default = false];
    if (has_java_multiple_files()) {
      total_size += 1 + 1;
    }

    // optional bool java_generate_equals_and_hash = 20 [default = false];
    if (has_java_generate_equals_and_hash()) {
      total_size += 2 + 1;
    }

    // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
    if (has_optimize_for()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->optimize_for());
    }

    // optional string go_package = 11;
    if (has_go_package()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->go_package());
    }

    // optional bool cc_generic_services = 16 [default = false];
    if (has_cc_generic_services()) {
      total_size += 2 + 1;
    }

    // optional bool java_generic_services = 17 [default = false];
    if (has_java_generic_services()) {
      total_size += 2 + 1;
    }

  }
  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    // optional bool py_generic_services = 18 [default = false];
    if (has_py_generic_services()) {
      total_size += 2 + 1;
    }

  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void FileOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const FileOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const FileOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void FileOptions::MergeFrom(const FileOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_java_package()) {
      set_java_package(from.java_package());
    }
    if (from.has_java_outer_classname()) {
      set_java_outer_classname(from.java_outer_classname());
    }
    if (from.has_java_multiple_files()) {
      set_java_multiple_files(from.java_multiple_files());
    }
    if (from.has_java_generate_equals_and_hash()) {
      set_java_generate_equals_and_hash(from.java_generate_equals_and_hash());
    }
    if (from.has_optimize_for()) {
      set_optimize_for(from.optimize_for());
    }
    if (from.has_go_package()) {
      set_go_package(from.go_package());
    }
    if (from.has_cc_generic_services()) {
      set_cc_generic_services(from.cc_generic_services());
    }
    if (from.has_java_generic_services()) {
      set_java_generic_services(from.java_generic_services());
    }
  }
  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    if (from.has_py_generic_services()) {
      set_py_generic_services(from.py_generic_services());
    }
  }
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void FileOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void FileOptions::CopyFrom(const FileOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FileOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void FileOptions::Swap(FileOptions* other) {
  if (other != this) {
    std::swap(java_package_, other->java_package_);
    std::swap(java_outer_classname_, other->java_outer_classname_);
    std::swap(java_multiple_files_, other->java_multiple_files_);
    std::swap(java_generate_equals_and_hash_, other->java_generate_equals_and_hash_);
    std::swap(optimize_for_, other->optimize_for_);
    std::swap(go_package_, other->go_package_);
    std::swap(cc_generic_services_, other->cc_generic_services_);
    std::swap(java_generic_services_, other->java_generic_services_);
    std::swap(py_generic_services_, other->py_generic_services_);
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata FileOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = FileOptions_descriptor_;
  metadata.reflection = FileOptions_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int MessageOptions::kMessageSetWireFormatFieldNumber;
const int MessageOptions::kNoStandardDescriptorAccessorFieldNumber;
const int MessageOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

MessageOptions::MessageOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void MessageOptions::InitAsDefaultInstance() {
}

MessageOptions::MessageOptions(const MessageOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void MessageOptions::SharedCtor() {
  _cached_size_ = 0;
  message_set_wire_format_ = false;
  no_standard_descriptor_accessor_ = false;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MessageOptions::~MessageOptions() {
  SharedDtor();
}

void MessageOptions::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MessageOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MessageOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MessageOptions_descriptor_;
}

const MessageOptions& MessageOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

MessageOptions* MessageOptions::default_instance_ = NULL;

MessageOptions* MessageOptions::New() const {
  return new MessageOptions;
}

void MessageOptions::Clear() {
  _extensions_.Clear();
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    message_set_wire_format_ = false;
    no_standard_descriptor_accessor_ = false;
  }
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MessageOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool message_set_wire_format = 1 [default = false];
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &message_set_wire_format_)));
          set_has_message_set_wire_format();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(16)) goto parse_no_standard_descriptor_accessor;
        break;
      }

      // optional bool no_standard_descriptor_accessor = 2 [default = false];
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_no_standard_descriptor_accessor:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &no_standard_descriptor_accessor_)));
          set_has_no_standard_descriptor_accessor();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void MessageOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional bool message_set_wire_format = 1 [default = false];
  if (has_message_set_wire_format()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(1, this->message_set_wire_format(), output);
  }

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  if (has_no_standard_descriptor_accessor()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->no_standard_descriptor_accessor(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* MessageOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional bool message_set_wire_format = 1 [default = false];
  if (has_message_set_wire_format()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(1, this->message_set_wire_format(), target);
  }

  // optional bool no_standard_descriptor_accessor = 2 [default = false];
  if (has_no_standard_descriptor_accessor()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->no_standard_descriptor_accessor(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int MessageOptions::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional bool message_set_wire_format = 1 [default = false];
    if (has_message_set_wire_format()) {
      total_size += 1 + 1;
    }

    // optional bool no_standard_descriptor_accessor = 2 [default = false];
    if (has_no_standard_descriptor_accessor()) {
      total_size += 1 + 1;
    }

  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MessageOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MessageOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MessageOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MessageOptions::MergeFrom(const MessageOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_message_set_wire_format()) {
      set_message_set_wire_format(from.message_set_wire_format());
    }
    if (from.has_no_standard_descriptor_accessor()) {
      set_no_standard_descriptor_accessor(from.no_standard_descriptor_accessor());
    }
  }
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MessageOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MessageOptions::CopyFrom(const MessageOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MessageOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void MessageOptions::Swap(MessageOptions* other) {
  if (other != this) {
    std::swap(message_set_wire_format_, other->message_set_wire_format_);
    std::swap(no_standard_descriptor_accessor_, other->no_standard_descriptor_accessor_);
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata MessageOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MessageOptions_descriptor_;
  metadata.reflection = MessageOptions_reflection_;
  return metadata;
}


// ===================================================================

const ::google::protobuf::EnumDescriptor* FieldOptions_CType_descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FieldOptions_CType_descriptor_;
}
bool FieldOptions_CType_IsValid(int value) {
  switch(value) {
    case 0:
    case 1:
    case 2:
      return true;
    default:
      return false;
  }
}

#ifndef _MSC_VER
const FieldOptions_CType FieldOptions::STRING;
const FieldOptions_CType FieldOptions::CORD;
const FieldOptions_CType FieldOptions::STRING_PIECE;
const FieldOptions_CType FieldOptions::CType_MIN;
const FieldOptions_CType FieldOptions::CType_MAX;
const int FieldOptions::CType_ARRAYSIZE;
#endif  // _MSC_VER
#ifndef _MSC_VER
const int FieldOptions::kCtypeFieldNumber;
const int FieldOptions::kPackedFieldNumber;
const int FieldOptions::kLazyFieldNumber;
const int FieldOptions::kDeprecatedFieldNumber;
const int FieldOptions::kExperimentalMapKeyFieldNumber;
const int FieldOptions::kWeakFieldNumber;
const int FieldOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

FieldOptions::FieldOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void FieldOptions::InitAsDefaultInstance() {
}

FieldOptions::FieldOptions(const FieldOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void FieldOptions::SharedCtor() {
  _cached_size_ = 0;
  ctype_ = 0;
  packed_ = false;
  lazy_ = false;
  deprecated_ = false;
  experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  weak_ = false;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

FieldOptions::~FieldOptions() {
  SharedDtor();
}

void FieldOptions::SharedDtor() {
  if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
    delete experimental_map_key_;
  }
  if (this != default_instance_) {
  }
}

void FieldOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* FieldOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return FieldOptions_descriptor_;
}

const FieldOptions& FieldOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

FieldOptions* FieldOptions::default_instance_ = NULL;

FieldOptions* FieldOptions::New() const {
  return new FieldOptions;
}

void FieldOptions::Clear() {
  _extensions_.Clear();
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    ctype_ = 0;
    packed_ = false;
    lazy_ = false;
    deprecated_ = false;
    if (has_experimental_map_key()) {
      if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
        experimental_map_key_->clear();
      }
    }
    weak_ = false;
  }
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool FieldOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FieldOptions_CType_IsValid(value)) {
            set_ctype(static_cast< ::google::protobuf::FieldOptions_CType >(value));
          } else {
            mutable_unknown_fields()->AddVarint(1, value);
          }
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(16)) goto parse_packed;
        break;
      }

      // optional bool packed = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_packed:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &packed_)));
          set_has_packed();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(24)) goto parse_deprecated;
        break;
      }

      // optional bool deprecated = 3 [default = false];
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_deprecated:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &deprecated_)));
          set_has_deprecated();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(40)) goto parse_lazy;
        break;
      }

      // optional bool lazy = 5 [default = false];
      case 5: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_lazy:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &lazy_)));
          set_has_lazy();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(74)) goto parse_experimental_map_key;
        break;
      }

      // optional string experimental_map_key = 9;
      case 9: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_experimental_map_key:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_experimental_map_key()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->experimental_map_key().data(), this->experimental_map_key().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(80)) goto parse_weak;
        break;
      }

      // optional bool weak = 10 [default = false];
      case 10: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_weak:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &weak_)));
          set_has_weak();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void FieldOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  if (has_ctype()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->ctype(), output);
  }

  // optional bool packed = 2;
  if (has_packed()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->packed(), output);
  }

  // optional bool deprecated = 3 [default = false];
  if (has_deprecated()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(3, this->deprecated(), output);
  }

  // optional bool lazy = 5 [default = false];
  if (has_lazy()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(5, this->lazy(), output);
  }

  // optional string experimental_map_key = 9;
  if (has_experimental_map_key()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->experimental_map_key().data(), this->experimental_map_key().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      9, this->experimental_map_key(), output);
  }

  // optional bool weak = 10 [default = false];
  if (has_weak()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(10, this->weak(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* FieldOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
  if (has_ctype()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteEnumToArray(
      1, this->ctype(), target);
  }

  // optional bool packed = 2;
  if (has_packed()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->packed(), target);
  }

  // optional bool deprecated = 3 [default = false];
  if (has_deprecated()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(3, this->deprecated(), target);
  }

  // optional bool lazy = 5 [default = false];
  if (has_lazy()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(5, this->lazy(), target);
  }

  // optional string experimental_map_key = 9;
  if (has_experimental_map_key()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->experimental_map_key().data(), this->experimental_map_key().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        9, this->experimental_map_key(), target);
  }

  // optional bool weak = 10 [default = false];
  if (has_weak()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(10, this->weak(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int FieldOptions::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional .google.protobuf.FieldOptions.CType ctype = 1 [default = STRING];
    if (has_ctype()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->ctype());
    }

    // optional bool packed = 2;
    if (has_packed()) {
      total_size += 1 + 1;
    }

    // optional bool lazy = 5 [default = false];
    if (has_lazy()) {
      total_size += 1 + 1;
    }

    // optional bool deprecated = 3 [default = false];
    if (has_deprecated()) {
      total_size += 1 + 1;
    }

    // optional string experimental_map_key = 9;
    if (has_experimental_map_key()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->experimental_map_key());
    }

    // optional bool weak = 10 [default = false];
    if (has_weak()) {
      total_size += 1 + 1;
    }

  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void FieldOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const FieldOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const FieldOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void FieldOptions::MergeFrom(const FieldOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_ctype()) {
      set_ctype(from.ctype());
    }
    if (from.has_packed()) {
      set_packed(from.packed());
    }
    if (from.has_lazy()) {
      set_lazy(from.lazy());
    }
    if (from.has_deprecated()) {
      set_deprecated(from.deprecated());
    }
    if (from.has_experimental_map_key()) {
      set_experimental_map_key(from.experimental_map_key());
    }
    if (from.has_weak()) {
      set_weak(from.weak());
    }
  }
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void FieldOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void FieldOptions::CopyFrom(const FieldOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool FieldOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void FieldOptions::Swap(FieldOptions* other) {
  if (other != this) {
    std::swap(ctype_, other->ctype_);
    std::swap(packed_, other->packed_);
    std::swap(lazy_, other->lazy_);
    std::swap(deprecated_, other->deprecated_);
    std::swap(experimental_map_key_, other->experimental_map_key_);
    std::swap(weak_, other->weak_);
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata FieldOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = FieldOptions_descriptor_;
  metadata.reflection = FieldOptions_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int EnumOptions::kAllowAliasFieldNumber;
const int EnumOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

EnumOptions::EnumOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void EnumOptions::InitAsDefaultInstance() {
}

EnumOptions::EnumOptions(const EnumOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void EnumOptions::SharedCtor() {
  _cached_size_ = 0;
  allow_alias_ = true;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

EnumOptions::~EnumOptions() {
  SharedDtor();
}

void EnumOptions::SharedDtor() {
  if (this != default_instance_) {
  }
}

void EnumOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* EnumOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return EnumOptions_descriptor_;
}

const EnumOptions& EnumOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

EnumOptions* EnumOptions::default_instance_ = NULL;

EnumOptions* EnumOptions::New() const {
  return new EnumOptions;
}

void EnumOptions::Clear() {
  _extensions_.Clear();
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    allow_alias_ = true;
  }
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool EnumOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional bool allow_alias = 2 [default = true];
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &allow_alias_)));
          set_has_allow_alias();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        break;
      }

      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void EnumOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // optional bool allow_alias = 2 [default = true];
  if (has_allow_alias()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->allow_alias(), output);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* EnumOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // optional bool allow_alias = 2 [default = true];
  if (has_allow_alias()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->allow_alias(), target);
  }

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int EnumOptions::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // optional bool allow_alias = 2 [default = true];
    if (has_allow_alias()) {
      total_size += 1 + 1;
    }

  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void EnumOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const EnumOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const EnumOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void EnumOptions::MergeFrom(const EnumOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_allow_alias()) {
      set_allow_alias(from.allow_alias());
    }
  }
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void EnumOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EnumOptions::CopyFrom(const EnumOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void EnumOptions::Swap(EnumOptions* other) {
  if (other != this) {
    std::swap(allow_alias_, other->allow_alias_);
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata EnumOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = EnumOptions_descriptor_;
  metadata.reflection = EnumOptions_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int EnumValueOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

EnumValueOptions::EnumValueOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void EnumValueOptions::InitAsDefaultInstance() {
}

EnumValueOptions::EnumValueOptions(const EnumValueOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void EnumValueOptions::SharedCtor() {
  _cached_size_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

EnumValueOptions::~EnumValueOptions() {
  SharedDtor();
}

void EnumValueOptions::SharedDtor() {
  if (this != default_instance_) {
  }
}

void EnumValueOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* EnumValueOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return EnumValueOptions_descriptor_;
}

const EnumValueOptions& EnumValueOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

EnumValueOptions* EnumValueOptions::default_instance_ = NULL;

EnumValueOptions* EnumValueOptions::New() const {
  return new EnumValueOptions;
}

void EnumValueOptions::Clear() {
  _extensions_.Clear();
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool EnumValueOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void EnumValueOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* EnumValueOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int EnumValueOptions::ByteSize() const {
  int total_size = 0;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void EnumValueOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const EnumValueOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const EnumValueOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void EnumValueOptions::MergeFrom(const EnumValueOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void EnumValueOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void EnumValueOptions::CopyFrom(const EnumValueOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool EnumValueOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void EnumValueOptions::Swap(EnumValueOptions* other) {
  if (other != this) {
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata EnumValueOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = EnumValueOptions_descriptor_;
  metadata.reflection = EnumValueOptions_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int ServiceOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

ServiceOptions::ServiceOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void ServiceOptions::InitAsDefaultInstance() {
}

ServiceOptions::ServiceOptions(const ServiceOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void ServiceOptions::SharedCtor() {
  _cached_size_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

ServiceOptions::~ServiceOptions() {
  SharedDtor();
}

void ServiceOptions::SharedDtor() {
  if (this != default_instance_) {
  }
}

void ServiceOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* ServiceOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return ServiceOptions_descriptor_;
}

const ServiceOptions& ServiceOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

ServiceOptions* ServiceOptions::default_instance_ = NULL;

ServiceOptions* ServiceOptions::New() const {
  return new ServiceOptions;
}

void ServiceOptions::Clear() {
  _extensions_.Clear();
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool ServiceOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void ServiceOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* ServiceOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int ServiceOptions::ByteSize() const {
  int total_size = 0;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void ServiceOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const ServiceOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const ServiceOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void ServiceOptions::MergeFrom(const ServiceOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void ServiceOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void ServiceOptions::CopyFrom(const ServiceOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool ServiceOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void ServiceOptions::Swap(ServiceOptions* other) {
  if (other != this) {
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata ServiceOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = ServiceOptions_descriptor_;
  metadata.reflection = ServiceOptions_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int MethodOptions::kUninterpretedOptionFieldNumber;
#endif  // !_MSC_VER

MethodOptions::MethodOptions()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void MethodOptions::InitAsDefaultInstance() {
}

MethodOptions::MethodOptions(const MethodOptions& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void MethodOptions::SharedCtor() {
  _cached_size_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

MethodOptions::~MethodOptions() {
  SharedDtor();
}

void MethodOptions::SharedDtor() {
  if (this != default_instance_) {
  }
}

void MethodOptions::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* MethodOptions::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return MethodOptions_descriptor_;
}

const MethodOptions& MethodOptions::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

MethodOptions* MethodOptions::default_instance_ = NULL;

MethodOptions* MethodOptions::New() const {
  return new MethodOptions;
}

void MethodOptions::Clear() {
  _extensions_.Clear();
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool MethodOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
      case 999: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_uninterpreted_option:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_uninterpreted_option()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(7994)) goto parse_uninterpreted_option;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        if ((8000u <= tag)) {
          DO_(_extensions_.ParseField(tag, input, default_instance_,
                                      mutable_unknown_fields()));
          continue;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void MethodOptions::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      999, this->uninterpreted_option(i), output);
  }

  // Extension range [1000, 536870912)
  _extensions_.SerializeWithCachedSizes(
      1000, 536870912, output);

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* MethodOptions::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        999, this->uninterpreted_option(i), target);
  }

  // Extension range [1000, 536870912)
  target = _extensions_.SerializeWithCachedSizesToArray(
      1000, 536870912, target);

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int MethodOptions::ByteSize() const {
  int total_size = 0;

  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }

  total_size += _extensions_.ByteSize();

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void MethodOptions::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const MethodOptions* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const MethodOptions*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void MethodOptions::MergeFrom(const MethodOptions& from) {
  GOOGLE_CHECK_NE(&from, this);
  uninterpreted_option_.MergeFrom(from.uninterpreted_option_);
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void MethodOptions::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void MethodOptions::CopyFrom(const MethodOptions& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool MethodOptions::IsInitialized() const {

  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }

  if (!_extensions_.IsInitialized()) return false;  return true;
}

void MethodOptions::Swap(MethodOptions* other) {
  if (other != this) {
    uninterpreted_option_.Swap(&other->uninterpreted_option_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
    _extensions_.Swap(&other->_extensions_);
  }
}

::google::protobuf::Metadata MethodOptions::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = MethodOptions_descriptor_;
  metadata.reflection = MethodOptions_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int UninterpretedOption_NamePart::kNamePartFieldNumber;
const int UninterpretedOption_NamePart::kIsExtensionFieldNumber;
#endif  // !_MSC_VER

UninterpretedOption_NamePart::UninterpretedOption_NamePart()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void UninterpretedOption_NamePart::InitAsDefaultInstance() {
}

UninterpretedOption_NamePart::UninterpretedOption_NamePart(const UninterpretedOption_NamePart& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void UninterpretedOption_NamePart::SharedCtor() {
  _cached_size_ = 0;
  name_part_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  is_extension_ = false;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

UninterpretedOption_NamePart::~UninterpretedOption_NamePart() {
  SharedDtor();
}

void UninterpretedOption_NamePart::SharedDtor() {
  if (name_part_ != &::google::protobuf::internal::kEmptyString) {
    delete name_part_;
  }
  if (this != default_instance_) {
  }
}

void UninterpretedOption_NamePart::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* UninterpretedOption_NamePart::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return UninterpretedOption_NamePart_descriptor_;
}

const UninterpretedOption_NamePart& UninterpretedOption_NamePart::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

UninterpretedOption_NamePart* UninterpretedOption_NamePart::default_instance_ = NULL;

UninterpretedOption_NamePart* UninterpretedOption_NamePart::New() const {
  return new UninterpretedOption_NamePart;
}

void UninterpretedOption_NamePart::Clear() {
  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (has_name_part()) {
      if (name_part_ != &::google::protobuf::internal::kEmptyString) {
        name_part_->clear();
      }
    }
    is_extension_ = false;
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool UninterpretedOption_NamePart::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // required string name_part = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_name_part()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->name_part().data(), this->name_part().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(16)) goto parse_is_extension;
        break;
      }

      // required bool is_extension = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_is_extension:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &is_extension_)));
          set_has_is_extension();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void UninterpretedOption_NamePart::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // required string name_part = 1;
  if (has_name_part()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name_part().data(), this->name_part().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      1, this->name_part(), output);
  }

  // required bool is_extension = 2;
  if (has_is_extension()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(2, this->is_extension(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* UninterpretedOption_NamePart::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // required string name_part = 1;
  if (has_name_part()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->name_part().data(), this->name_part().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        1, this->name_part(), target);
  }

  // required bool is_extension = 2;
  if (has_is_extension()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(2, this->is_extension(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int UninterpretedOption_NamePart::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    // required string name_part = 1;
    if (has_name_part()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->name_part());
    }

    // required bool is_extension = 2;
    if (has_is_extension()) {
      total_size += 1 + 1;
    }

  }
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void UninterpretedOption_NamePart::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const UninterpretedOption_NamePart* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption_NamePart*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void UninterpretedOption_NamePart::MergeFrom(const UninterpretedOption_NamePart& from) {
  GOOGLE_CHECK_NE(&from, this);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_name_part()) {
      set_name_part(from.name_part());
    }
    if (from.has_is_extension()) {
      set_is_extension(from.is_extension());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void UninterpretedOption_NamePart::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void UninterpretedOption_NamePart::CopyFrom(const UninterpretedOption_NamePart& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool UninterpretedOption_NamePart::IsInitialized() const {
  if ((_has_bits_[0] & 0x00000003) != 0x00000003) return false;

  return true;
}

void UninterpretedOption_NamePart::Swap(UninterpretedOption_NamePart* other) {
  if (other != this) {
    std::swap(name_part_, other->name_part_);
    std::swap(is_extension_, other->is_extension_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata UninterpretedOption_NamePart::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = UninterpretedOption_NamePart_descriptor_;
  metadata.reflection = UninterpretedOption_NamePart_reflection_;
  return metadata;
}


// -------------------------------------------------------------------

#ifndef _MSC_VER
const int UninterpretedOption::kNameFieldNumber;
const int UninterpretedOption::kIdentifierValueFieldNumber;
const int UninterpretedOption::kPositiveIntValueFieldNumber;
const int UninterpretedOption::kNegativeIntValueFieldNumber;
const int UninterpretedOption::kDoubleValueFieldNumber;
const int UninterpretedOption::kStringValueFieldNumber;
const int UninterpretedOption::kAggregateValueFieldNumber;
#endif  // !_MSC_VER

UninterpretedOption::UninterpretedOption()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void UninterpretedOption::InitAsDefaultInstance() {
}

UninterpretedOption::UninterpretedOption(const UninterpretedOption& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void UninterpretedOption::SharedCtor() {
  _cached_size_ = 0;
  identifier_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  positive_int_value_ = GOOGLE_ULONGLONG(0);
  negative_int_value_ = GOOGLE_LONGLONG(0);
  double_value_ = 0;
  string_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  aggregate_value_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

UninterpretedOption::~UninterpretedOption() {
  SharedDtor();
}

void UninterpretedOption::SharedDtor() {
  if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
    delete identifier_value_;
  }
  if (string_value_ != &::google::protobuf::internal::kEmptyString) {
    delete string_value_;
  }
  if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
    delete aggregate_value_;
  }
  if (this != default_instance_) {
  }
}

void UninterpretedOption::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* UninterpretedOption::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return UninterpretedOption_descriptor_;
}

const UninterpretedOption& UninterpretedOption::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

UninterpretedOption* UninterpretedOption::default_instance_ = NULL;

UninterpretedOption* UninterpretedOption::New() const {
  return new UninterpretedOption;
}

void UninterpretedOption::Clear() {
  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    if (has_identifier_value()) {
      if (identifier_value_ != &::google::protobuf::internal::kEmptyString) {
        identifier_value_->clear();
      }
    }
    positive_int_value_ = GOOGLE_ULONGLONG(0);
    negative_int_value_ = GOOGLE_LONGLONG(0);
    double_value_ = 0;
    if (has_string_value()) {
      if (string_value_ != &::google::protobuf::internal::kEmptyString) {
        string_value_->clear();
      }
    }
    if (has_aggregate_value()) {
      if (aggregate_value_ != &::google::protobuf::internal::kEmptyString) {
        aggregate_value_->clear();
      }
    }
  }
  name_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool UninterpretedOption::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_name:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_name()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_name;
        if (input->ExpectTag(26)) goto parse_identifier_value;
        break;
      }

      // optional string identifier_value = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_identifier_value:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_identifier_value()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->identifier_value().data(), this->identifier_value().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(32)) goto parse_positive_int_value;
        break;
      }

      // optional uint64 positive_int_value = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_positive_int_value:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::uint64, ::google::protobuf::internal::WireFormatLite::TYPE_UINT64>(
                 input, &positive_int_value_)));
          set_has_positive_int_value();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(40)) goto parse_negative_int_value;
        break;
      }

      // optional int64 negative_int_value = 5;
      case 5: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_negative_int_value:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   ::google::protobuf::int64, ::google::protobuf::internal::WireFormatLite::TYPE_INT64>(
                 input, &negative_int_value_)));
          set_has_negative_int_value();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(49)) goto parse_double_value;
        break;
      }

      // optional double double_value = 6;
      case 6: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_FIXED64) {
         parse_double_value:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   double, ::google::protobuf::internal::WireFormatLite::TYPE_DOUBLE>(
                 input, &double_value_)));
          set_has_double_value();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(58)) goto parse_string_value;
        break;
      }

      // optional bytes string_value = 7;
      case 7: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_string_value:
          DO_(::google::protobuf::internal::WireFormatLite::ReadBytes(
                input, this->mutable_string_value()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(66)) goto parse_aggregate_value;
        break;
      }

      // optional string aggregate_value = 8;
      case 8: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_aggregate_value:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_aggregate_value()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->aggregate_value().data(), this->aggregate_value().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void UninterpretedOption::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  for (int i = 0; i < this->name_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      2, this->name(i), output);
  }

  // optional string identifier_value = 3;
  if (has_identifier_value()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->identifier_value().data(), this->identifier_value().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      3, this->identifier_value(), output);
  }

  // optional uint64 positive_int_value = 4;
  if (has_positive_int_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteUInt64(4, this->positive_int_value(), output);
  }

  // optional int64 negative_int_value = 5;
  if (has_negative_int_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteInt64(5, this->negative_int_value(), output);
  }

  // optional double double_value = 6;
  if (has_double_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteDouble(6, this->double_value(), output);
  }

  // optional bytes string_value = 7;
  if (has_string_value()) {
    ::google::protobuf::internal::WireFormatLite::WriteBytes(
      7, this->string_value(), output);
  }

  // optional string aggregate_value = 8;
  if (has_aggregate_value()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->aggregate_value().data(), this->aggregate_value().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      8, this->aggregate_value(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* UninterpretedOption::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  for (int i = 0; i < this->name_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        2, this->name(i), target);
  }

  // optional string identifier_value = 3;
  if (has_identifier_value()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->identifier_value().data(), this->identifier_value().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->identifier_value(), target);
  }

  // optional uint64 positive_int_value = 4;
  if (has_positive_int_value()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteUInt64ToArray(4, this->positive_int_value(), target);
  }

  // optional int64 negative_int_value = 5;
  if (has_negative_int_value()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteInt64ToArray(5, this->negative_int_value(), target);
  }

  // optional double double_value = 6;
  if (has_double_value()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteDoubleToArray(6, this->double_value(), target);
  }

  // optional bytes string_value = 7;
  if (has_string_value()) {
    target =
      ::google::protobuf::internal::WireFormatLite::WriteBytesToArray(
        7, this->string_value(), target);
  }

  // optional string aggregate_value = 8;
  if (has_aggregate_value()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->aggregate_value().data(), this->aggregate_value().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        8, this->aggregate_value(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int UninterpretedOption::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    // optional string identifier_value = 3;
    if (has_identifier_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->identifier_value());
    }

    // optional uint64 positive_int_value = 4;
    if (has_positive_int_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::UInt64Size(
          this->positive_int_value());
    }

    // optional int64 negative_int_value = 5;
    if (has_negative_int_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int64Size(
          this->negative_int_value());
    }

    // optional double double_value = 6;
    if (has_double_value()) {
      total_size += 1 + 8;
    }

    // optional bytes string_value = 7;
    if (has_string_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::BytesSize(
          this->string_value());
    }

    // optional string aggregate_value = 8;
    if (has_aggregate_value()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->aggregate_value());
    }

  }
  // repeated .google.protobuf.UninterpretedOption.NamePart name = 2;
  total_size += 1 * this->name_size();
  for (int i = 0; i < this->name_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->name(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void UninterpretedOption::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const UninterpretedOption* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const UninterpretedOption*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void UninterpretedOption::MergeFrom(const UninterpretedOption& from) {
  GOOGLE_CHECK_NE(&from, this);
  name_.MergeFrom(from.name_);
  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    if (from.has_identifier_value()) {
      set_identifier_value(from.identifier_value());
    }
    if (from.has_positive_int_value()) {
      set_positive_int_value(from.positive_int_value());
    }
    if (from.has_negative_int_value()) {
      set_negative_int_value(from.negative_int_value());
    }
    if (from.has_double_value()) {
      set_double_value(from.double_value());
    }
    if (from.has_string_value()) {
      set_string_value(from.string_value());
    }
    if (from.has_aggregate_value()) {
      set_aggregate_value(from.aggregate_value());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void UninterpretedOption::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void UninterpretedOption::CopyFrom(const UninterpretedOption& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool UninterpretedOption::IsInitialized() const {

  for (int i = 0; i < name_size(); i++) {
    if (!this->name(i).IsInitialized()) return false;
  }
  return true;
}

void UninterpretedOption::Swap(UninterpretedOption* other) {
  if (other != this) {
    name_.Swap(&other->name_);
    std::swap(identifier_value_, other->identifier_value_);
    std::swap(positive_int_value_, other->positive_int_value_);
    std::swap(negative_int_value_, other->negative_int_value_);
    std::swap(double_value_, other->double_value_);
    std::swap(string_value_, other->string_value_);
    std::swap(aggregate_value_, other->aggregate_value_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata UninterpretedOption::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = UninterpretedOption_descriptor_;
  metadata.reflection = UninterpretedOption_reflection_;
  return metadata;
}


// ===================================================================

#ifndef _MSC_VER
const int SourceCodeInfo_Location::kPathFieldNumber;
const int SourceCodeInfo_Location::kSpanFieldNumber;
const int SourceCodeInfo_Location::kLeadingCommentsFieldNumber;
const int SourceCodeInfo_Location::kTrailingCommentsFieldNumber;
#endif  // !_MSC_VER

SourceCodeInfo_Location::SourceCodeInfo_Location()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void SourceCodeInfo_Location::InitAsDefaultInstance() {
}

SourceCodeInfo_Location::SourceCodeInfo_Location(const SourceCodeInfo_Location& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void SourceCodeInfo_Location::SharedCtor() {
  _cached_size_ = 0;
  leading_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  trailing_comments_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

SourceCodeInfo_Location::~SourceCodeInfo_Location() {
  SharedDtor();
}

void SourceCodeInfo_Location::SharedDtor() {
  if (leading_comments_ != &::google::protobuf::internal::kEmptyString) {
    delete leading_comments_;
  }
  if (trailing_comments_ != &::google::protobuf::internal::kEmptyString) {
    delete trailing_comments_;
  }
  if (this != default_instance_) {
  }
}

void SourceCodeInfo_Location::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* SourceCodeInfo_Location::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return SourceCodeInfo_Location_descriptor_;
}

const SourceCodeInfo_Location& SourceCodeInfo_Location::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

SourceCodeInfo_Location* SourceCodeInfo_Location::default_instance_ = NULL;

SourceCodeInfo_Location* SourceCodeInfo_Location::New() const {
  return new SourceCodeInfo_Location;
}

void SourceCodeInfo_Location::Clear() {
  if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) {
    if (has_leading_comments()) {
      if (leading_comments_ != &::google::protobuf::internal::kEmptyString) {
        leading_comments_->clear();
      }
    }
    if (has_trailing_comments()) {
      if (trailing_comments_ != &::google::protobuf::internal::kEmptyString) {
        trailing_comments_->clear();
      }
    }
  }
  path_.Clear();
  span_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool SourceCodeInfo_Location::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated int32 path = 1 [packed = true];
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_path())));
        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
                   == ::google::protobuf::internal::WireFormatLite::
                      WIRETYPE_VARINT) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 10, input, this->mutable_path())));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(18)) goto parse_span;
        break;
      }

      // repeated int32 span = 2 [packed = true];
      case 2: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_span:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPackedPrimitive<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 input, this->mutable_span())));
        } else if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag)
                   == ::google::protobuf::internal::WireFormatLite::
                      WIRETYPE_VARINT) {
          DO_((::google::protobuf::internal::WireFormatLite::ReadRepeatedPrimitiveNoInline<
                   ::google::protobuf::int32, ::google::protobuf::internal::WireFormatLite::TYPE_INT32>(
                 1, 18, input, this->mutable_span())));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_leading_comments;
        break;
      }

      // optional string leading_comments = 3;
      case 3: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_leading_comments:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_leading_comments()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->leading_comments().data(), this->leading_comments().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(34)) goto parse_trailing_comments;
        break;
      }

      // optional string trailing_comments = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_trailing_comments:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_trailing_comments()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->trailing_comments().data(), this->trailing_comments().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void SourceCodeInfo_Location::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated int32 path = 1 [packed = true];
  if (this->path_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(1, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_path_cached_byte_size_);
  }
  for (int i = 0; i < this->path_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
      this->path(i), output);
  }

  // repeated int32 span = 2 [packed = true];
  if (this->span_size() > 0) {
    ::google::protobuf::internal::WireFormatLite::WriteTag(2, ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED, output);
    output->WriteVarint32(_span_cached_byte_size_);
  }
  for (int i = 0; i < this->span_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteInt32NoTag(
      this->span(i), output);
  }

  // optional string leading_comments = 3;
  if (has_leading_comments()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->leading_comments().data(), this->leading_comments().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      3, this->leading_comments(), output);
  }

  // optional string trailing_comments = 4;
  if (has_trailing_comments()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->trailing_comments().data(), this->trailing_comments().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    ::google::protobuf::internal::WireFormatLite::WriteString(
      4, this->trailing_comments(), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* SourceCodeInfo_Location::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated int32 path = 1 [packed = true];
  if (this->path_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      1,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _path_cached_byte_size_, target);
  }
  for (int i = 0; i < this->path_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32NoTagToArray(this->path(i), target);
  }

  // repeated int32 span = 2 [packed = true];
  if (this->span_size() > 0) {
    target = ::google::protobuf::internal::WireFormatLite::WriteTagToArray(
      2,
      ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED,
      target);
    target = ::google::protobuf::io::CodedOutputStream::WriteVarint32ToArray(
      _span_cached_byte_size_, target);
  }
  for (int i = 0; i < this->span_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteInt32NoTagToArray(this->span(i), target);
  }

  // optional string leading_comments = 3;
  if (has_leading_comments()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->leading_comments().data(), this->leading_comments().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        3, this->leading_comments(), target);
  }

  // optional string trailing_comments = 4;
  if (has_trailing_comments()) {
    ::google::protobuf::internal::WireFormat::VerifyUTF8String(
      this->trailing_comments().data(), this->trailing_comments().length(),
      ::google::protobuf::internal::WireFormat::SERIALIZE);
    target =
      ::google::protobuf::internal::WireFormatLite::WriteStringToArray(
        4, this->trailing_comments(), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int SourceCodeInfo_Location::ByteSize() const {
  int total_size = 0;

  if (_has_bits_[2 / 32] & (0xffu << (2 % 32))) {
    // optional string leading_comments = 3;
    if (has_leading_comments()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->leading_comments());
    }

    // optional string trailing_comments = 4;
    if (has_trailing_comments()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->trailing_comments());
    }

  }
  // repeated int32 path = 1 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->path_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        Int32Size(this->path(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _path_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  // repeated int32 span = 2 [packed = true];
  {
    int data_size = 0;
    for (int i = 0; i < this->span_size(); i++) {
      data_size += ::google::protobuf::internal::WireFormatLite::
        Int32Size(this->span(i));
    }
    if (data_size > 0) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::Int32Size(data_size);
    }
    GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
    _span_cached_byte_size_ = data_size;
    GOOGLE_SAFE_CONCURRENT_WRITES_END();
    total_size += data_size;
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void SourceCodeInfo_Location::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const SourceCodeInfo_Location* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo_Location*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void SourceCodeInfo_Location::MergeFrom(const SourceCodeInfo_Location& from) {
  GOOGLE_CHECK_NE(&from, this);
  path_.MergeFrom(from.path_);
  span_.MergeFrom(from.span_);
  if (from._has_bits_[2 / 32] & (0xffu << (2 % 32))) {
    if (from.has_leading_comments()) {
      set_leading_comments(from.leading_comments());
    }
    if (from.has_trailing_comments()) {
      set_trailing_comments(from.trailing_comments());
    }
  }
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void SourceCodeInfo_Location::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void SourceCodeInfo_Location::CopyFrom(const SourceCodeInfo_Location& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SourceCodeInfo_Location::IsInitialized() const {

  return true;
}

void SourceCodeInfo_Location::Swap(SourceCodeInfo_Location* other) {
  if (other != this) {
    path_.Swap(&other->path_);
    span_.Swap(&other->span_);
    std::swap(leading_comments_, other->leading_comments_);
    std::swap(trailing_comments_, other->trailing_comments_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata SourceCodeInfo_Location::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = SourceCodeInfo_Location_descriptor_;
  metadata.reflection = SourceCodeInfo_Location_reflection_;
  return metadata;
}


// -------------------------------------------------------------------

#ifndef _MSC_VER
const int SourceCodeInfo::kLocationFieldNumber;
#endif  // !_MSC_VER

SourceCodeInfo::SourceCodeInfo()
  : ::google::protobuf::Message() {
  SharedCtor();
}

void SourceCodeInfo::InitAsDefaultInstance() {
}

SourceCodeInfo::SourceCodeInfo(const SourceCodeInfo& from)
  : ::google::protobuf::Message() {
  SharedCtor();
  MergeFrom(from);
}

void SourceCodeInfo::SharedCtor() {
  _cached_size_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

SourceCodeInfo::~SourceCodeInfo() {
  SharedDtor();
}

void SourceCodeInfo::SharedDtor() {
  if (this != default_instance_) {
  }
}

void SourceCodeInfo::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const ::google::protobuf::Descriptor* SourceCodeInfo::descriptor() {
  protobuf_AssignDescriptorsOnce();
  return SourceCodeInfo_descriptor_;
}

const SourceCodeInfo& SourceCodeInfo::default_instance() {
  if (default_instance_ == NULL) protobuf_AddDesc_google_2fprotobuf_2fdescriptor_2eproto();
  return *default_instance_;
}

SourceCodeInfo* SourceCodeInfo::default_instance_ = NULL;

SourceCodeInfo* SourceCodeInfo::New() const {
  return new SourceCodeInfo;
}

void SourceCodeInfo::Clear() {
  location_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool SourceCodeInfo::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_location:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_location()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(10)) goto parse_location;
        if (input->ExpectAtEnd()) return true;
        break;
      }

      default: {
      handle_uninterpreted:
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          return true;
        }
        DO_(::google::protobuf::internal::WireFormat::SkipField(
              input, tag, mutable_unknown_fields()));
        break;
      }
    }
  }
  return true;
#undef DO_
}

void SourceCodeInfo::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  for (int i = 0; i < this->location_size(); i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessageMaybeToArray(
      1, this->location(i), output);
  }

  if (!unknown_fields().empty()) {
    ::google::protobuf::internal::WireFormat::SerializeUnknownFields(
        unknown_fields(), output);
  }
}

::google::protobuf::uint8* SourceCodeInfo::SerializeWithCachedSizesToArray(
    ::google::protobuf::uint8* target) const {
  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  for (int i = 0; i < this->location_size(); i++) {
    target = ::google::protobuf::internal::WireFormatLite::
      WriteMessageNoVirtualToArray(
        1, this->location(i), target);
  }

  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int SourceCodeInfo::ByteSize() const {
  int total_size = 0;

  // repeated .google.protobuf.SourceCodeInfo.Location location = 1;
  total_size += 1 * this->location_size();
  for (int i = 0; i < this->location_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->location(i));
  }

  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormat::ComputeUnknownFieldsSize(
        unknown_fields());
  }
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void SourceCodeInfo::MergeFrom(const ::google::protobuf::Message& from) {
  GOOGLE_CHECK_NE(&from, this);
  const SourceCodeInfo* source =
    ::google::protobuf::internal::dynamic_cast_if_available<const SourceCodeInfo*>(
      &from);
  if (source == NULL) {
    ::google::protobuf::internal::ReflectionOps::Merge(from, this);
  } else {
    MergeFrom(*source);
  }
}

void SourceCodeInfo::MergeFrom(const SourceCodeInfo& from) {
  GOOGLE_CHECK_NE(&from, this);
  location_.MergeFrom(from.location_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

void SourceCodeInfo::CopyFrom(const ::google::protobuf::Message& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

void SourceCodeInfo::CopyFrom(const SourceCodeInfo& from) {
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SourceCodeInfo::IsInitialized() const {

  return true;
}

void SourceCodeInfo::Swap(SourceCodeInfo* other) {
  if (other != this) {
    location_.Swap(&other->location_);
    std::swap(_has_bits_[0], other->_has_bits_[0]);
    _unknown_fields_.Swap(&other->_unknown_fields_);
    std::swap(_cached_size_, other->_cached_size_);
  }
}

::google::protobuf::Metadata SourceCodeInfo::GetMetadata() const {
  protobuf_AssignDescriptorsOnce();
  ::google::protobuf::Metadata metadata;
  metadata.descriptor = SourceCodeInfo_descriptor_;
  metadata.reflection = SourceCodeInfo_reflection_;
  return metadata;
}


// @@protoc_insertion_point(namespace_scope)

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)
