// Generated by the protocol buffer compiler.  DO NOT EDIT!

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

#include <algorithm>

#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/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_[9] = {
    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, 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_[9] = {
    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, 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_[5] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, ctype_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FieldOptions, packed_),
    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, 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_[1] = {
    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_[2] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, path_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(SourceCodeInfo_Location, span_),
  };
  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\"\227\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"
    "6\n\014message_type\030\004 \003(\0132 .google.protobuf."
    "DescriptorProto\0227\n\tenum_type\030\005 \003(\0132$.goo"
    "gle.protobuf.EnumDescriptorProto\0228\n\007serv"
    "ice\030\006 \003(\0132\'.google.protobuf.ServiceDescr"
    "iptorProto\0228\n\textension\030\007 \003(\0132%.google.p"
    "rotobuf.FieldDescriptorProto\022-\n\007options\030"
    "\010 \001(\0132\034.google.protobuf.FileOptions\0229\n\020s"
    "ource_code_info\030\t \001(\0132\037.google.protobuf."
    "SourceCodeInfo\"\251\003\n\017DescriptorProto\022\014\n\004na"
    "me\030\001 \001(\t\0224\n\005field\030\002 \003(\0132%.google.protobu"
    "f.FieldDescriptorProto\0228\n\textension\030\006 \003("
    "\0132%.google.protobuf.FieldDescriptorProto"
    "\0225\n\013nested_type\030\003 \003(\0132 .google.protobuf."
    "DescriptorProto\0227\n\tenum_type\030\004 \003(\0132$.goo"
    "gle.protobuf.EnumDescriptorProto\022H\n\017exte"
    "nsion_range\030\005 \003(\0132/.google.protobuf.Desc"
    "riptorProto.ExtensionRange\0220\n\007options\030\007 "
    "\001(\0132\037.google.protobuf.MessageOptions\032,\n\016"
    "ExtensionRange\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+.googl"
    "e.protobuf.FieldDescriptorProto.Label\0228\n"
    "\004type\030\005 \001(\0162*.google.protobuf.FieldDescr"
    "iptorProto.Type\022\021\n\ttype_name\030\006 \001(\t\022\020\n\010ex"
    "tendee\030\002 \001(\t\022\025\n\rdefault_value\030\007 \001(\t\022.\n\007o"
    "ptions\030\010 \001(\0132\035.google.protobuf.FieldOpti"
    "ons\"\266\002\n\004Type\022\017\n\013TYPE_DOUBLE\020\001\022\016\n\nTYPE_FL"
    "OAT\020\002\022\016\n\nTYPE_INT64\020\003\022\017\n\013TYPE_UINT64\020\004\022\016"
    "\n\nTYPE_INT32\020\005\022\020\n\014TYPE_FIXED64\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_MESSAGE\020\013\022\016\n\n"
    "TYPE_BYTES\020\014\022\017\n\013TYPE_UINT32\020\r\022\r\n\tTYPE_EN"
    "UM\020\016\022\021\n\rTYPE_SFIXED32\020\017\022\021\n\rTYPE_SFIXED64"
    "\020\020\022\017\n\013TYPE_SINT32\020\021\022\017\n\013TYPE_SINT64\020\022\"C\n\005"
    "Label\022\022\n\016LABEL_OPTIONAL\020\001\022\022\n\016LABEL_REQUI"
    "RED\020\002\022\022\n\016LABEL_REPEATED\020\003\"\214\001\n\023EnumDescri"
    "ptorProto\022\014\n\004name\030\001 \001(\t\0228\n\005value\030\002 \003(\0132)"
    ".google.protobuf.EnumValueDescriptorProt"
    "o\022-\n\007options\030\003 \001(\0132\034.google.protobuf.Enu"
    "mOptions\"l\n\030EnumValueDescriptorProto\022\014\n\004"
    "name\030\001 \001(\t\022\016\n\006number\030\002 \001(\005\0222\n\007options\030\003 "
    "\001(\0132!.google.protobuf.EnumValueOptions\"\220"
    "\001\n\026ServiceDescriptorProto\022\014\n\004name\030\001 \001(\t\022"
    "6\n\006method\030\002 \003(\0132&.google.protobuf.Method"
    "DescriptorProto\0220\n\007options\030\003 \001(\0132\037.googl"
    "e.protobuf.ServiceOptions\"\177\n\025MethodDescr"
    "iptorProto\022\014\n\004name\030\001 \001(\t\022\022\n\ninput_type\030\002"
    " \001(\t\022\023\n\013output_type\030\003 \001(\t\022/\n\007options\030\004 \001"
    "(\0132\036.google.protobuf.MethodOptions\"\325\003\n\013F"
    "ileOptions\022\024\n\014java_package\030\001 \001(\t\022\034\n\024java"
    "_outer_classname\030\010 \001(\t\022\"\n\023java_multiple_"
    "files\030\n \001(\010:\005false\022,\n\035java_generate_equa"
    "ls_and_hash\030\024 \001(\010:\005false\022F\n\014optimize_for"
    "\030\t \001(\0162).google.protobuf.FileOptions.Opt"
    "imizeMode:\005SPEED\022\"\n\023cc_generic_services\030"
    "\020 \001(\010:\005false\022$\n\025java_generic_services\030\021 "
    "\001(\010:\005false\022\"\n\023py_generic_services\030\022 \001(\010:"
    "\005false\022C\n\024uninterpreted_option\030\347\007 \003(\0132$."
    "google.protobuf.UninterpretedOption\":\n\014O"
    "ptimizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n"
    "\014LITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOp"
    "tions\022&\n\027message_set_wire_format\030\001 \001(\010:\005"
    "false\022.\n\037no_standard_descriptor_accessor"
    "\030\002 \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007"
    " \003(\0132$.google.protobuf.UninterpretedOpti"
    "on*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptions\022:\n\005ctype\030"
    "\001 \001(\0162#.google.protobuf.FieldOptions.CTy"
    "pe:\006STRING\022\016\n\006packed\030\002 \001(\010\022\031\n\ndeprecated"
    "\030\003 \001(\010:\005false\022\034\n\024experimental_map_key\030\t "
    "\001(\t\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goo"
    "gle.protobuf.UninterpretedOption\"/\n\005CTyp"
    "e\022\n\n\006STRING\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\"]\n\013EnumOptions\022C\n\024uninterpr"
    "eted_option\030\347\007 \003(\0132$.google.protobuf.Uni"
    "nterpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020EnumValue"
    "Options\022C\n\024uninterpreted_option\030\347\007 \003(\0132$"
    ".google.protobuf.UninterpretedOption*\t\010\350"
    "\007\020\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninterpret"
    "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
    "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethodOptio"
    "ns\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.goog"
    "le.protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200"
    "\200\002\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\013"
    "2-.google.protobuf.UninterpretedOption.N"
    "amePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022pos"
    "itive_int_value\030\004 \001(\004\022\032\n\022negative_int_va"
    "lue\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014strin"
    "g_value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323"
    "\n\010NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_exte"
    "nsion\030\002 \002(\010\"|\n\016SourceCodeInfo\022:\n\010locatio"
    "n\030\001 \003(\0132(.google.protobuf.SourceCodeInfo"
    ".Location\032.\n\010Location\022\020\n\004path\030\001 \003(\005B\002\020\001\022"
    "\020\n\004span\030\002 \003(\005B\002\020\001B)\n\023com.google.protobuf"
    "B\020DescriptorProtosH\001", 3940);
  ::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::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_options()) {
      if (options_ != NULL) options_->::google::protobuf::FileOptions::Clear();
    }
  }
  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    if (has_source_code_info()) {
      if (source_code_info_ != NULL) source_code_info_->::google::protobuf::SourceCodeInfo::Clear();
    }
  }
  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(0).data(), this->dependency(0).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->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);
  }
  
  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);
  }
  
  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());
    }
    
    // optional .google.protobuf.FileOptions options = 8;
    if (has_options()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
          this->options());
    }
    
  }
  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    // 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 .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_);
  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_options()) {
      mutable_options()->::google::protobuf::FileOptions::MergeFrom(from.options());
    }
  }
  if (from._has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    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_);
    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::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;
  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 (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;
    cc_generic_services_ = false;
    java_generic_services_ = false;
    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(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 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 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 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;
    }
    
    // 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_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_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(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::kDeprecatedFieldNumber;
const int FieldOptions::kExperimentalMapKeyFieldNumber;
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;
  deprecated_ = false;
  experimental_map_key_ = const_cast< ::std::string*>(&::google::protobuf::internal::kEmptyString);
  ::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;
    deprecated_ = false;
    if (has_experimental_map_key()) {
      if (experimental_map_key_ != &::google::protobuf::internal::kEmptyString) {
        experimental_map_key_->clear();
      }
    }
  }
  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(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(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 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);
  }
  
  // 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 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);
  }
  
  // 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 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());
    }
    
  }
  // 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_deprecated()) {
      set_deprecated(from.deprecated());
    }
    if (from.has_experimental_map_key()) {
      set_experimental_map_key(from.experimental_map_key());
    }
  }
  _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(deprecated_, other->deprecated_);
    std::swap(experimental_map_key_, other->experimental_map_key_);
    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::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;
  ::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();
  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)) {
      // 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 {
  // 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 {
  // 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;
  
  // 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_);
  _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) {
    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;
#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;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

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

void SourceCodeInfo_Location::SharedDtor() {
  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() {
  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->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);
  }
  
  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);
  }
  
  if (!unknown_fields().empty()) {
    target = ::google::protobuf::internal::WireFormat::SerializeUnknownFieldsToArray(
        unknown_fields(), target);
  }
  return target;
}

int SourceCodeInfo_Location::ByteSize() const {
  int total_size = 0;
  
  // 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);
    }
    _path_cached_byte_size_ = data_size;
    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);
    }
    _span_cached_byte_size_ = data_size;
    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_);
  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(_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)
