// 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_[10] = {
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_package_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_outer_classname_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, java_multiple_files_),
    GOOGLE_PROTOBUF_GENERATED_MESSAGE_FIELD_OFFSET(FileOptions, retain_unknown_fields_),
    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\"\373\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\025retain_unknown_fie"
    "lds\030\013 \001(\010:\005false\022,\n\035java_generate_equals"
    "_and_hash\030\024 \001(\010:\005false\022F\n\014optimize_for\030\t"
    " \001(\0162).google.protobuf.FileOptions.Optim"
    "izeMode:\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:\005f"
    "alse\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.go"
    "ogle.protobuf.UninterpretedOption\":\n\014Opt"
    "imizeMode\022\t\n\005SPEED\020\001\022\r\n\tCODE_SIZE\020\002\022\020\n\014L"
    "ITE_RUNTIME\020\003*\t\010\350\007\020\200\200\200\200\002\"\270\001\n\016MessageOpti"
    "ons\022&\n\027message_set_wire_format\030\001 \001(\010:\005fa"
    "lse\022.\n\037no_standard_descriptor_accessor\030\002"
    " \001(\010:\005false\022C\n\024uninterpreted_option\030\347\007 \003"
    "(\0132$.google.protobuf.UninterpretedOption"
    "*\t\010\350\007\020\200\200\200\200\002\"\224\002\n\014FieldOptions\022:\n\005ctype\030\001 "
    "\001(\0162#.google.protobuf.FieldOptions.CType"
    ":\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$.googl"
    "e.protobuf.UninterpretedOption\"/\n\005CType\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\024uninterpret"
    "ed_option\030\347\007 \003(\0132$.google.protobuf.Unint"
    "erpretedOption*\t\010\350\007\020\200\200\200\200\002\"b\n\020EnumValueOp"
    "tions\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.g"
    "oogle.protobuf.UninterpretedOption*\t\010\350\007\020"
    "\200\200\200\200\002\"`\n\016ServiceOptions\022C\n\024uninterpreted"
    "_option\030\347\007 \003(\0132$.google.protobuf.Uninter"
    "pretedOption*\t\010\350\007\020\200\200\200\200\002\"_\n\rMethodOptions"
    "\022C\n\024uninterpreted_option\030\347\007 \003(\0132$.google"
    ".protobuf.UninterpretedOption*\t\010\350\007\020\200\200\200\200\002"
    "\"\236\002\n\023UninterpretedOption\022;\n\004name\030\002 \003(\0132-"
    ".google.protobuf.UninterpretedOption.Nam"
    "ePart\022\030\n\020identifier_value\030\003 \001(\t\022\032\n\022posit"
    "ive_int_value\030\004 \001(\004\022\032\n\022negative_int_valu"
    "e\030\005 \001(\003\022\024\n\014double_value\030\006 \001(\001\022\024\n\014string_"
    "value\030\007 \001(\014\022\027\n\017aggregate_value\030\010 \001(\t\0323\n\010"
    "NamePart\022\021\n\tname_part\030\001 \002(\t\022\024\n\014is_extens"
    "ion\030\002 \002(\010\"|\n\016SourceCodeInfo\022:\n\010location\030"
    "\001 \003(\0132(.google.protobuf.SourceCodeInfo.L"
    "ocation\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.protobufB\020"
    "DescriptorProtosH\001", 3978);
  ::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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(this->dependency_size() - 1).data(),
            this->dependency(this->dependency_size() - 1).length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(26)) goto parse_dependency;
        if (input->ExpectTag(34)) goto parse_message_type;
        break;
      }
      
      // repeated .google.protobuf.DescriptorProto message_type = 4;
      case 4: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_message_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_message_type()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(34)) goto parse_message_type;
        if (input->ExpectTag(42)) goto parse_enum_type;
        break;
      }
      
      // repeated .google.protobuf.EnumDescriptorProto enum_type = 5;
      case 5: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_enum_type:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_enum_type()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(42)) goto parse_enum_type;
        if (input->ExpectTag(50)) goto parse_service;
        break;
      }
      
      // repeated .google.protobuf.ServiceDescriptorProto service = 6;
      case 6: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_service:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_service()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(50)) goto parse_service;
        if (input->ExpectTag(58)) goto parse_extension;
        break;
      }
      
      // repeated .google.protobuf.FieldDescriptorProto extension = 7;
      case 7: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_extension:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
                input, add_extension()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(58)) goto parse_extension;
        if (input->ExpectTag(66)) goto parse_options;
        break;
      }
      
      // optional .google.protobuf.FileOptions options = 8;
      case 8: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_options:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_options()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(74)) goto parse_source_code_info;
        break;
      }
      
      // optional .google.protobuf.SourceCodeInfo source_code_info = 9;
      case 9: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_source_code_info:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtual(
               input, mutable_source_code_info()));
        } else {
          goto handle_uninterpreted;
        }
        if (input->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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::kRetainUnknownFieldsFieldNumber;
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;
  retain_unknown_fields_ = 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;
    retain_unknown_fields_ = false;
    java_generate_equals_and_hash_ = false;
    optimize_for_ = 1;
    cc_generic_services_ = false;
    java_generic_services_ = false;
  }
  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    py_generic_services_ = false;
  }
  uninterpreted_option_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  mutable_unknown_fields()->Clear();
}

bool FileOptions::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!(EXPRESSION)) return false
  ::google::protobuf::uint32 tag;
  while ((tag = input->ReadTag()) != 0) {
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string java_package = 1;
      case 1: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_java_package()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->java_package().data(), this->java_package().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(66)) goto parse_java_outer_classname;
        break;
      }
      
      // optional string java_outer_classname = 8;
      case 8: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_LENGTH_DELIMITED) {
         parse_java_outer_classname:
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_java_outer_classname()));
          ::google::protobuf::internal::WireFormat::VerifyUTF8String(
            this->java_outer_classname().data(), this->java_outer_classname().length(),
            ::google::protobuf::internal::WireFormat::PARSE);
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(72)) goto parse_optimize_for;
        break;
      }
      
      // optional .google.protobuf.FileOptions.OptimizeMode optimize_for = 9 [default = SPEED];
      case 9: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_optimize_for:
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::google::protobuf::FileOptions_OptimizeMode_IsValid(value)) {
            set_optimize_for(static_cast< ::google::protobuf::FileOptions_OptimizeMode >(value));
          } else {
            mutable_unknown_fields()->AddVarint(9, value);
          }
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(80)) goto parse_java_multiple_files;
        break;
      }
      
      // optional bool java_multiple_files = 10 [default = false];
      case 10: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_java_multiple_files:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &java_multiple_files_)));
          set_has_java_multiple_files();
        } else {
          goto handle_uninterpreted;
        }
        if (input->ExpectTag(88)) goto parse_retain_unknown_fields;
        break;
      }
      
      // optional bool retain_unknown_fields = 11 [default = false];
      case 11: {
        if (::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_VARINT) {
         parse_retain_unknown_fields:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &retain_unknown_fields_)));
          set_has_retain_unknown_fields();
        } 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::WireFormatLite::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 retain_unknown_fields = 11 [default = false];
  if (has_retain_unknown_fields()) {
    ::google::protobuf::internal::WireFormatLite::WriteBool(11, this->retain_unknown_fields(), 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::WireFormatLite::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 retain_unknown_fields = 11 [default = false];
  if (has_retain_unknown_fields()) {
    target = ::google::protobuf::internal::WireFormatLite::WriteBoolToArray(11, this->retain_unknown_fields(), 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::WireFormatLite::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 retain_unknown_fields = 11 [default = false];
    if (has_retain_unknown_fields()) {
      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;
    }
    
  }
  if (_has_bits_[8 / 32] & (0xffu << (8 % 32))) {
    // optional bool py_generic_services = 18 [default = false];
    if (has_py_generic_services()) {
      total_size += 2 + 1;
    }
    
  }
  // repeated .google.protobuf.UninterpretedOption uninterpreted_option = 999;
  total_size += 2 * this->uninterpreted_option_size();
  for (int i = 0; i < this->uninterpreted_option_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->uninterpreted_option(i));
  }
  
  total_size += _extensions_.ByteSize();
  
  if (!unknown_fields().empty()) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::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_retain_unknown_fields()) {
      set_retain_unknown_fields(from.retain_unknown_fields());
    }
    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_bits_[8 / 32] & (0xffu << (8 % 32))) {
    if (from.has_py_generic_services()) {
      set_py_generic_services(from.py_generic_services());
    }
  }
  _extensions_.MergeFrom(from._extensions_);
  mutable_unknown_fields()->MergeFrom(from.unknown_fields());
}

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

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

bool FileOptions::IsInitialized() const {
  
  for (int i = 0; i < uninterpreted_option_size(); i++) {
    if (!this->uninterpreted_option(i).IsInitialized()) return false;
  }
  
  if (!_extensions_.IsInitialized()) return false;  return true;
}

void FileOptions::Swap(FileOptions* other) {
  if (other != this) {
    std::swap(java_package_, other->java_package_);
    std::swap(java_outer_classname_, other->java_outer_classname_);
    std::swap(java_multiple_files_, other->java_multiple_files_);
    std::swap(retain_unknown_fields_, other->retain_unknown_fields_);
    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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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::WireFormatLite::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)
