// Generated by the protocol buffer compiler.  DO NOT EDIT!
// source: Types.proto

#ifndef GOOGLE_PROTOBUF_INCLUDED_Types_2eproto
#define GOOGLE_PROTOBUF_INCLUDED_Types_2eproto

#include <limits>
#include <string>

#include <google/protobuf/port_def.inc>
#if PROTOBUF_VERSION < 3016000
#error This file was generated by a newer version of protoc which is
#error incompatible with your Protocol Buffer headers. Please update
#error your headers.
#endif
#if 3016003 < PROTOBUF_MIN_PROTOC_VERSION
#error This file was generated by an older version of protoc which is
#error incompatible with your Protocol Buffer headers. Please
#error regenerate this file with a newer version of protoc.
#endif

#include <google/protobuf/port_undef.inc>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/arena.h>
#include <google/protobuf/arenastring.h>
#include <google/protobuf/generated_message_table_driven.h>
#include <google/protobuf/generated_message_util.h>
#include <google/protobuf/metadata_lite.h>
#include <google/protobuf/generated_message_reflection.h>
#include <google/protobuf/message.h>
#include <google/protobuf/repeated_field.h>  // IWYU pragma: export
#include <google/protobuf/extension_set.h>  // IWYU pragma: export
#include <google/protobuf/generated_enum_reflection.h>
#include <google/protobuf/unknown_field_set.h>
// @@protoc_insertion_point(includes)
#include <google/protobuf/port_def.inc>
#define PROTOBUF_INTERNAL_EXPORT_Types_2eproto
PROTOBUF_NAMESPACE_OPEN
namespace internal {
class AnyMetadata;
}  // namespace internal
PROTOBUF_NAMESPACE_CLOSE

// Internal implementation detail -- do not use these members.
struct TableStruct_Types_2eproto {
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTableField entries[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::AuxiliaryParseTableField aux[]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::ParseTable schema[1]
    PROTOBUF_SECTION_VARIABLE(protodesc_cold);
  static const ::PROTOBUF_NAMESPACE_ID::internal::FieldMetadata field_metadata[];
  static const ::PROTOBUF_NAMESPACE_ID::internal::SerializationTable serialization_table[];
  static const ::PROTOBUF_NAMESPACE_ID::uint32 offsets[];
};
extern const ::PROTOBUF_NAMESPACE_ID::internal::DescriptorTable descriptor_table_Types_2eproto;
namespace common {
class MajorType;
struct MajorTypeDefaultTypeInternal;
extern MajorTypeDefaultTypeInternal _MajorType_default_instance_;
}  // namespace common
PROTOBUF_NAMESPACE_OPEN
template<> ::common::MajorType* Arena::CreateMaybeMessage<::common::MajorType>(Arena*);
PROTOBUF_NAMESPACE_CLOSE
namespace common {

enum MinorType : int {
  LATE = 0,
  MAP = 1,
  TINYINT = 3,
  SMALLINT = 4,
  INT = 5,
  BIGINT = 6,
  DECIMAL9 = 7,
  DECIMAL18 = 8,
  DECIMAL28SPARSE = 9,
  DECIMAL38SPARSE = 10,
  MONEY = 11,
  DATE = 12,
  TIME = 13,
  TIMETZ = 14,
  TIMESTAMPTZ = 15,
  TIMESTAMP = 16,
  INTERVAL = 17,
  FLOAT4 = 18,
  FLOAT8 = 19,
  BIT = 20,
  FIXEDCHAR = 21,
  FIXED16CHAR = 22,
  FIXEDBINARY = 23,
  VARCHAR = 24,
  VAR16CHAR = 25,
  VARBINARY = 26,
  UINT1 = 29,
  UINT2 = 30,
  UINT4 = 31,
  UINT8 = 32,
  DECIMAL28DENSE = 33,
  DECIMAL38DENSE = 34,
  DM_UNKNOWN = 37,
  INTERVALYEAR = 38,
  INTERVALDAY = 39,
  LIST = 40,
  GENERIC_OBJECT = 41,
  UNION = 42,
  VARDECIMAL = 43,
  DICT = 44
};
bool MinorType_IsValid(int value);
constexpr MinorType MinorType_MIN = LATE;
constexpr MinorType MinorType_MAX = DICT;
constexpr int MinorType_ARRAYSIZE = MinorType_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* MinorType_descriptor();
template<typename T>
inline const std::string& MinorType_Name(T enum_t_value) {
  static_assert(::std::is_same<T, MinorType>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function MinorType_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    MinorType_descriptor(), enum_t_value);
}
inline bool MinorType_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, MinorType* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<MinorType>(
    MinorType_descriptor(), name, value);
}
enum DataMode : int {
  DM_OPTIONAL = 0,
  DM_REQUIRED = 1,
  DM_REPEATED = 2
};
bool DataMode_IsValid(int value);
constexpr DataMode DataMode_MIN = DM_OPTIONAL;
constexpr DataMode DataMode_MAX = DM_REPEATED;
constexpr int DataMode_ARRAYSIZE = DataMode_MAX + 1;

const ::PROTOBUF_NAMESPACE_ID::EnumDescriptor* DataMode_descriptor();
template<typename T>
inline const std::string& DataMode_Name(T enum_t_value) {
  static_assert(::std::is_same<T, DataMode>::value ||
    ::std::is_integral<T>::value,
    "Incorrect type passed to function DataMode_Name.");
  return ::PROTOBUF_NAMESPACE_ID::internal::NameOfEnum(
    DataMode_descriptor(), enum_t_value);
}
inline bool DataMode_Parse(
    ::PROTOBUF_NAMESPACE_ID::ConstStringParam name, DataMode* value) {
  return ::PROTOBUF_NAMESPACE_ID::internal::ParseNamedEnum<DataMode>(
    DataMode_descriptor(), name, value);
}
// ===================================================================

class MajorType PROTOBUF_FINAL :
    public ::PROTOBUF_NAMESPACE_ID::Message /* @@protoc_insertion_point(class_definition:common.MajorType) */ {
 public:
  inline MajorType() : MajorType(nullptr) {}
  ~MajorType() override;
  explicit constexpr MajorType(::PROTOBUF_NAMESPACE_ID::internal::ConstantInitialized);

  MajorType(const MajorType& from);
  MajorType(MajorType&& from) noexcept
    : MajorType() {
    *this = ::std::move(from);
  }

  inline MajorType& operator=(const MajorType& from) {
    CopyFrom(from);
    return *this;
  }
  inline MajorType& operator=(MajorType&& from) noexcept {
    if (GetArena() == from.GetArena()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }

  inline const ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>(::PROTOBUF_NAMESPACE_ID::UnknownFieldSet::default_instance);
  }
  inline ::PROTOBUF_NAMESPACE_ID::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields<::PROTOBUF_NAMESPACE_ID::UnknownFieldSet>();
  }

  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* descriptor() {
    return GetDescriptor();
  }
  static const ::PROTOBUF_NAMESPACE_ID::Descriptor* GetDescriptor() {
    return default_instance().GetMetadata().descriptor;
  }
  static const ::PROTOBUF_NAMESPACE_ID::Reflection* GetReflection() {
    return default_instance().GetMetadata().reflection;
  }
  static const MajorType& default_instance() {
    return *internal_default_instance();
  }
  static inline const MajorType* internal_default_instance() {
    return reinterpret_cast<const MajorType*>(
               &_MajorType_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  friend void swap(MajorType& a, MajorType& b) {
    a.Swap(&b);
  }
  inline void Swap(MajorType* other) {
    if (other == this) return;
    if (GetArena() == other->GetArena()) {
      InternalSwap(other);
    } else {
      ::PROTOBUF_NAMESPACE_ID::internal::GenericSwap(this, other);
    }
  }
  void UnsafeArenaSwap(MajorType* other) {
    if (other == this) return;
    GOOGLE_DCHECK(GetArena() == other->GetArena());
    InternalSwap(other);
  }

  // implements Message ----------------------------------------------

  inline MajorType* New() const final {
    return CreateMaybeMessage<MajorType>(nullptr);
  }

  MajorType* New(::PROTOBUF_NAMESPACE_ID::Arena* arena) const final {
    return CreateMaybeMessage<MajorType>(arena);
  }
  void CopyFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void MergeFrom(const ::PROTOBUF_NAMESPACE_ID::Message& from) final;
  void CopyFrom(const MajorType& from);
  void MergeFrom(const MajorType& from);
  PROTOBUF_ATTRIBUTE_REINITIALIZES void Clear() final;
  bool IsInitialized() const final;

  size_t ByteSizeLong() const final;
  const char* _InternalParse(const char* ptr, ::PROTOBUF_NAMESPACE_ID::internal::ParseContext* ctx) final;
  ::PROTOBUF_NAMESPACE_ID::uint8* _InternalSerialize(
      ::PROTOBUF_NAMESPACE_ID::uint8* target, ::PROTOBUF_NAMESPACE_ID::io::EpsCopyOutputStream* stream) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  inline void SharedCtor();
  inline void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(MajorType* other);
  friend class ::PROTOBUF_NAMESPACE_ID::internal::AnyMetadata;
  static ::PROTOBUF_NAMESPACE_ID::StringPiece FullMessageName() {
    return "common.MajorType";
  }
  protected:
  explicit MajorType(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  private:
  static void ArenaDtor(void* object);
  inline void RegisterArenaDtor(::PROTOBUF_NAMESPACE_ID::Arena* arena);
  public:

  ::PROTOBUF_NAMESPACE_ID::Metadata GetMetadata() const final;

  // nested types ----------------------------------------------------

  // accessors -------------------------------------------------------

  enum : int {
    kSubTypeFieldNumber = 7,
    kMinorTypeFieldNumber = 1,
    kModeFieldNumber = 2,
    kWidthFieldNumber = 3,
    kPrecisionFieldNumber = 4,
    kScaleFieldNumber = 5,
    kTimeZoneFieldNumber = 6,
  };
  // repeated .common.MinorType sub_type = 7;
  int sub_type_size() const;
  private:
  int _internal_sub_type_size() const;
  public:
  void clear_sub_type();
  private:
  ::common::MinorType _internal_sub_type(int index) const;
  void _internal_add_sub_type(::common::MinorType value);
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* _internal_mutable_sub_type();
  public:
  ::common::MinorType sub_type(int index) const;
  void set_sub_type(int index, ::common::MinorType value);
  void add_sub_type(::common::MinorType value);
  const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>& sub_type() const;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>* mutable_sub_type();

  // optional .common.MinorType minor_type = 1;
  bool has_minor_type() const;
  private:
  bool _internal_has_minor_type() const;
  public:
  void clear_minor_type();
  ::common::MinorType minor_type() const;
  void set_minor_type(::common::MinorType value);
  private:
  ::common::MinorType _internal_minor_type() const;
  void _internal_set_minor_type(::common::MinorType value);
  public:

  // optional .common.DataMode mode = 2;
  bool has_mode() const;
  private:
  bool _internal_has_mode() const;
  public:
  void clear_mode();
  ::common::DataMode mode() const;
  void set_mode(::common::DataMode value);
  private:
  ::common::DataMode _internal_mode() const;
  void _internal_set_mode(::common::DataMode value);
  public:

  // optional int32 width = 3;
  bool has_width() const;
  private:
  bool _internal_has_width() const;
  public:
  void clear_width();
  ::PROTOBUF_NAMESPACE_ID::int32 width() const;
  void set_width(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_width() const;
  void _internal_set_width(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 precision = 4;
  bool has_precision() const;
  private:
  bool _internal_has_precision() const;
  public:
  void clear_precision();
  ::PROTOBUF_NAMESPACE_ID::int32 precision() const;
  void set_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_precision() const;
  void _internal_set_precision(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 scale = 5;
  bool has_scale() const;
  private:
  bool _internal_has_scale() const;
  public:
  void clear_scale();
  ::PROTOBUF_NAMESPACE_ID::int32 scale() const;
  void set_scale(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_scale() const;
  void _internal_set_scale(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // optional int32 timeZone = 6;
  bool has_timezone() const;
  private:
  bool _internal_has_timezone() const;
  public:
  void clear_timezone();
  ::PROTOBUF_NAMESPACE_ID::int32 timezone() const;
  void set_timezone(::PROTOBUF_NAMESPACE_ID::int32 value);
  private:
  ::PROTOBUF_NAMESPACE_ID::int32 _internal_timezone() const;
  void _internal_set_timezone(::PROTOBUF_NAMESPACE_ID::int32 value);
  public:

  // @@protoc_insertion_point(class_scope:common.MajorType)
 private:
  class _Internal;

  template <typename T> friend class ::PROTOBUF_NAMESPACE_ID::Arena::InternalHelper;
  typedef void InternalArenaConstructable_;
  typedef void DestructorSkippable_;
  ::PROTOBUF_NAMESPACE_ID::internal::HasBits<1> _has_bits_;
  mutable ::PROTOBUF_NAMESPACE_ID::internal::CachedSize _cached_size_;
  ::PROTOBUF_NAMESPACE_ID::RepeatedField<int> sub_type_;
  int minor_type_;
  int mode_;
  ::PROTOBUF_NAMESPACE_ID::int32 width_;
  ::PROTOBUF_NAMESPACE_ID::int32 precision_;
  ::PROTOBUF_NAMESPACE_ID::int32 scale_;
  ::PROTOBUF_NAMESPACE_ID::int32 timezone_;
  friend struct ::TableStruct_Types_2eproto;
};
// ===================================================================


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

#ifdef __GNUC__
  #pragma GCC diagnostic push
  #pragma GCC diagnostic ignored "-Wstrict-aliasing"
#endif  // __GNUC__
// MajorType

// optional .common.MinorType minor_type = 1;
inline bool MajorType::_internal_has_minor_type() const {
  bool value = (_has_bits_[0] & 0x00000001u) != 0;
  return value;
}
inline bool MajorType::has_minor_type() const {
  return _internal_has_minor_type();
}
inline void MajorType::clear_minor_type() {
  minor_type_ = 0;
  _has_bits_[0] &= ~0x00000001u;
}
inline ::common::MinorType MajorType::_internal_minor_type() const {
  return static_cast< ::common::MinorType >(minor_type_);
}
inline ::common::MinorType MajorType::minor_type() const {
  // @@protoc_insertion_point(field_get:common.MajorType.minor_type)
  return _internal_minor_type();
}
inline void MajorType::_internal_set_minor_type(::common::MinorType value) {
  assert(::common::MinorType_IsValid(value));
  _has_bits_[0] |= 0x00000001u;
  minor_type_ = value;
}
inline void MajorType::set_minor_type(::common::MinorType value) {
  _internal_set_minor_type(value);
  // @@protoc_insertion_point(field_set:common.MajorType.minor_type)
}

// optional .common.DataMode mode = 2;
inline bool MajorType::_internal_has_mode() const {
  bool value = (_has_bits_[0] & 0x00000002u) != 0;
  return value;
}
inline bool MajorType::has_mode() const {
  return _internal_has_mode();
}
inline void MajorType::clear_mode() {
  mode_ = 0;
  _has_bits_[0] &= ~0x00000002u;
}
inline ::common::DataMode MajorType::_internal_mode() const {
  return static_cast< ::common::DataMode >(mode_);
}
inline ::common::DataMode MajorType::mode() const {
  // @@protoc_insertion_point(field_get:common.MajorType.mode)
  return _internal_mode();
}
inline void MajorType::_internal_set_mode(::common::DataMode value) {
  assert(::common::DataMode_IsValid(value));
  _has_bits_[0] |= 0x00000002u;
  mode_ = value;
}
inline void MajorType::set_mode(::common::DataMode value) {
  _internal_set_mode(value);
  // @@protoc_insertion_point(field_set:common.MajorType.mode)
}

// optional int32 width = 3;
inline bool MajorType::_internal_has_width() const {
  bool value = (_has_bits_[0] & 0x00000004u) != 0;
  return value;
}
inline bool MajorType::has_width() const {
  return _internal_has_width();
}
inline void MajorType::clear_width() {
  width_ = 0;
  _has_bits_[0] &= ~0x00000004u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::_internal_width() const {
  return width_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::width() const {
  // @@protoc_insertion_point(field_get:common.MajorType.width)
  return _internal_width();
}
inline void MajorType::_internal_set_width(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000004u;
  width_ = value;
}
inline void MajorType::set_width(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_width(value);
  // @@protoc_insertion_point(field_set:common.MajorType.width)
}

// optional int32 precision = 4;
inline bool MajorType::_internal_has_precision() const {
  bool value = (_has_bits_[0] & 0x00000008u) != 0;
  return value;
}
inline bool MajorType::has_precision() const {
  return _internal_has_precision();
}
inline void MajorType::clear_precision() {
  precision_ = 0;
  _has_bits_[0] &= ~0x00000008u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::_internal_precision() const {
  return precision_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::precision() const {
  // @@protoc_insertion_point(field_get:common.MajorType.precision)
  return _internal_precision();
}
inline void MajorType::_internal_set_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000008u;
  precision_ = value;
}
inline void MajorType::set_precision(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_precision(value);
  // @@protoc_insertion_point(field_set:common.MajorType.precision)
}

// optional int32 scale = 5;
inline bool MajorType::_internal_has_scale() const {
  bool value = (_has_bits_[0] & 0x00000010u) != 0;
  return value;
}
inline bool MajorType::has_scale() const {
  return _internal_has_scale();
}
inline void MajorType::clear_scale() {
  scale_ = 0;
  _has_bits_[0] &= ~0x00000010u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::_internal_scale() const {
  return scale_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::scale() const {
  // @@protoc_insertion_point(field_get:common.MajorType.scale)
  return _internal_scale();
}
inline void MajorType::_internal_set_scale(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000010u;
  scale_ = value;
}
inline void MajorType::set_scale(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_scale(value);
  // @@protoc_insertion_point(field_set:common.MajorType.scale)
}

// optional int32 timeZone = 6;
inline bool MajorType::_internal_has_timezone() const {
  bool value = (_has_bits_[0] & 0x00000020u) != 0;
  return value;
}
inline bool MajorType::has_timezone() const {
  return _internal_has_timezone();
}
inline void MajorType::clear_timezone() {
  timezone_ = 0;
  _has_bits_[0] &= ~0x00000020u;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::_internal_timezone() const {
  return timezone_;
}
inline ::PROTOBUF_NAMESPACE_ID::int32 MajorType::timezone() const {
  // @@protoc_insertion_point(field_get:common.MajorType.timeZone)
  return _internal_timezone();
}
inline void MajorType::_internal_set_timezone(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _has_bits_[0] |= 0x00000020u;
  timezone_ = value;
}
inline void MajorType::set_timezone(::PROTOBUF_NAMESPACE_ID::int32 value) {
  _internal_set_timezone(value);
  // @@protoc_insertion_point(field_set:common.MajorType.timeZone)
}

// repeated .common.MinorType sub_type = 7;
inline int MajorType::_internal_sub_type_size() const {
  return sub_type_.size();
}
inline int MajorType::sub_type_size() const {
  return _internal_sub_type_size();
}
inline void MajorType::clear_sub_type() {
  sub_type_.Clear();
}
inline ::common::MinorType MajorType::_internal_sub_type(int index) const {
  return static_cast< ::common::MinorType >(sub_type_.Get(index));
}
inline ::common::MinorType MajorType::sub_type(int index) const {
  // @@protoc_insertion_point(field_get:common.MajorType.sub_type)
  return _internal_sub_type(index);
}
inline void MajorType::set_sub_type(int index, ::common::MinorType value) {
  assert(::common::MinorType_IsValid(value));
  sub_type_.Set(index, value);
  // @@protoc_insertion_point(field_set:common.MajorType.sub_type)
}
inline void MajorType::_internal_add_sub_type(::common::MinorType value) {
  assert(::common::MinorType_IsValid(value));
  sub_type_.Add(value);
}
inline void MajorType::add_sub_type(::common::MinorType value) {
  // @@protoc_insertion_point(field_add:common.MajorType.sub_type)
  _internal_add_sub_type(value);
}
inline const ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>&
MajorType::sub_type() const {
  // @@protoc_insertion_point(field_list:common.MajorType.sub_type)
  return sub_type_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
MajorType::_internal_mutable_sub_type() {
  return &sub_type_;
}
inline ::PROTOBUF_NAMESPACE_ID::RepeatedField<int>*
MajorType::mutable_sub_type() {
  // @@protoc_insertion_point(field_mutable_list:common.MajorType.sub_type)
  return _internal_mutable_sub_type();
}

#ifdef __GNUC__
  #pragma GCC diagnostic pop
#endif  // __GNUC__

// @@protoc_insertion_point(namespace_scope)

}  // namespace common

PROTOBUF_NAMESPACE_OPEN

template <> struct is_proto_enum< ::common::MinorType> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::common::MinorType>() {
  return ::common::MinorType_descriptor();
}
template <> struct is_proto_enum< ::common::DataMode> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::common::DataMode>() {
  return ::common::DataMode_descriptor();
}

PROTOBUF_NAMESPACE_CLOSE

// @@protoc_insertion_point(global_scope)

#include <google/protobuf/port_undef.inc>
#endif  // GOOGLE_PROTOBUF_INCLUDED_GOOGLE_PROTOBUF_INCLUDED_Types_2eproto
