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

#ifndef PROTOBUF_INCLUDED_api_2eproto
#define PROTOBUF_INCLUDED_api_2eproto

#include <string>

#include <google/protobuf/stubs/common.h>

#if GOOGLE_PROTOBUF_VERSION < 3006001
#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 3006001 < GOOGLE_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/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/inlined_string_field.h>
#include <google/protobuf/metadata.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)
#define PROTOBUF_INTERNAL_EXPORT_protobuf_api_2eproto

namespace protobuf_api_2eproto {
// Internal implementation detail -- do not use these members.
struct TableStruct {
  static const ::google::protobuf::internal::ParseTableField entries[];
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
  static const ::google::protobuf::internal::ParseTable schema[5];
  static const ::google::protobuf::internal::FieldMetadata field_metadata[];
  static const ::google::protobuf::internal::SerializationTable serialization_table[];
  static const ::google::protobuf::uint32 offsets[];
};
void AddDescriptors();
}  // namespace protobuf_api_2eproto
namespace api {
class RICControlHeader;
class RICControlHeaderDefaultTypeInternal;
extern RICControlHeaderDefaultTypeInternal _RICControlHeader_default_instance_;
class RICControlMessage;
class RICControlMessageDefaultTypeInternal;
extern RICControlMessageDefaultTypeInternal _RICControlMessage_default_instance_;
class RICE2APHeader;
class RICE2APHeaderDefaultTypeInternal;
extern RICE2APHeaderDefaultTypeInternal _RICE2APHeader_default_instance_;
class RicControlGrpcReq;
class RicControlGrpcReqDefaultTypeInternal;
extern RicControlGrpcReqDefaultTypeInternal _RicControlGrpcReq_default_instance_;
class RicControlGrpcRsp;
class RicControlGrpcRspDefaultTypeInternal;
extern RicControlGrpcRspDefaultTypeInternal _RicControlGrpcRsp_default_instance_;
}  // namespace api
namespace google {
namespace protobuf {
template<> ::api::RICControlHeader* Arena::CreateMaybeMessage<::api::RICControlHeader>(Arena*);
template<> ::api::RICControlMessage* Arena::CreateMaybeMessage<::api::RICControlMessage>(Arena*);
template<> ::api::RICE2APHeader* Arena::CreateMaybeMessage<::api::RICE2APHeader>(Arena*);
template<> ::api::RicControlGrpcReq* Arena::CreateMaybeMessage<::api::RicControlGrpcReq>(Arena*);
template<> ::api::RicControlGrpcRsp* Arena::CreateMaybeMessage<::api::RicControlGrpcRsp>(Arena*);
}  // namespace protobuf
}  // namespace google
namespace api {

enum RICControlCellTypeEnum {
  RIC_CONTROL_CELL_UNKWON = 0,
  RIC_CONTROL_NR_CELL = 1,
  RIC_CONTROL_EUTRAN_CELL = 2,
  RICControlCellTypeEnum_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
  RICControlCellTypeEnum_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
};
bool RICControlCellTypeEnum_IsValid(int value);
const RICControlCellTypeEnum RICControlCellTypeEnum_MIN = RIC_CONTROL_CELL_UNKWON;
const RICControlCellTypeEnum RICControlCellTypeEnum_MAX = RIC_CONTROL_EUTRAN_CELL;
const int RICControlCellTypeEnum_ARRAYSIZE = RICControlCellTypeEnum_MAX + 1;

const ::google::protobuf::EnumDescriptor* RICControlCellTypeEnum_descriptor();
inline const ::std::string& RICControlCellTypeEnum_Name(RICControlCellTypeEnum value) {
  return ::google::protobuf::internal::NameOfEnum(
    RICControlCellTypeEnum_descriptor(), value);
}
inline bool RICControlCellTypeEnum_Parse(
    const ::std::string& name, RICControlCellTypeEnum* value) {
  return ::google::protobuf::internal::ParseNamedEnum<RICControlCellTypeEnum>(
    RICControlCellTypeEnum_descriptor(), name, value);
}
enum RICControlAckEnum {
  RIC_CONTROL_ACK_UNKWON = 0,
  RIC_CONTROL_NO_ACK = 1,
  RIC_CONTROL_ACK = 2,
  RIC_CONTROL_NACK = 3,
  RICControlAckEnum_INT_MIN_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32min,
  RICControlAckEnum_INT_MAX_SENTINEL_DO_NOT_USE_ = ::google::protobuf::kint32max
};
bool RICControlAckEnum_IsValid(int value);
const RICControlAckEnum RICControlAckEnum_MIN = RIC_CONTROL_ACK_UNKWON;
const RICControlAckEnum RICControlAckEnum_MAX = RIC_CONTROL_NACK;
const int RICControlAckEnum_ARRAYSIZE = RICControlAckEnum_MAX + 1;

const ::google::protobuf::EnumDescriptor* RICControlAckEnum_descriptor();
inline const ::std::string& RICControlAckEnum_Name(RICControlAckEnum value) {
  return ::google::protobuf::internal::NameOfEnum(
    RICControlAckEnum_descriptor(), value);
}
inline bool RICControlAckEnum_Parse(
    const ::std::string& name, RICControlAckEnum* value) {
  return ::google::protobuf::internal::ParseNamedEnum<RICControlAckEnum>(
    RICControlAckEnum_descriptor(), name, value);
}
// ===================================================================

class RICE2APHeader : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:api.RICE2APHeader) */ {
 public:
  RICE2APHeader();
  virtual ~RICE2APHeader();

  RICE2APHeader(const RICE2APHeader& from);

  inline RICE2APHeader& operator=(const RICE2APHeader& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  RICE2APHeader(RICE2APHeader&& from) noexcept
    : RICE2APHeader() {
    *this = ::std::move(from);
  }

  inline RICE2APHeader& operator=(RICE2APHeader&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor();
  static const RICE2APHeader& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const RICE2APHeader* internal_default_instance() {
    return reinterpret_cast<const RICE2APHeader*>(
               &_RICE2APHeader_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    0;

  void Swap(RICE2APHeader* other);
  friend void swap(RICE2APHeader& a, RICE2APHeader& b) {
    a.Swap(&b);
  }

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

  inline RICE2APHeader* New() const final {
    return CreateMaybeMessage<RICE2APHeader>(NULL);
  }

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RICE2APHeader* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // int64 RanFuncId = 1;
  void clear_ranfuncid();
  static const int kRanFuncIdFieldNumber = 1;
  ::google::protobuf::int64 ranfuncid() const;
  void set_ranfuncid(::google::protobuf::int64 value);

  // int64 RICRequestorID = 2;
  void clear_ricrequestorid();
  static const int kRICRequestorIDFieldNumber = 2;
  ::google::protobuf::int64 ricrequestorid() const;
  void set_ricrequestorid(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:api.RICE2APHeader)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::int64 ranfuncid_;
  ::google::protobuf::int64 ricrequestorid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_api_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class RICControlHeader : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:api.RICControlHeader) */ {
 public:
  RICControlHeader();
  virtual ~RICControlHeader();

  RICControlHeader(const RICControlHeader& from);

  inline RICControlHeader& operator=(const RICControlHeader& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  RICControlHeader(RICControlHeader&& from) noexcept
    : RICControlHeader() {
    *this = ::std::move(from);
  }

  inline RICControlHeader& operator=(RICControlHeader&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor();
  static const RICControlHeader& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const RICControlHeader* internal_default_instance() {
    return reinterpret_cast<const RICControlHeader*>(
               &_RICControlHeader_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    1;

  void Swap(RICControlHeader* other);
  friend void swap(RICControlHeader& a, RICControlHeader& b) {
    a.Swap(&b);
  }

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

  inline RICControlHeader* New() const final {
    return CreateMaybeMessage<RICControlHeader>(NULL);
  }

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RICControlHeader* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // string UEID = 3;
  void clear_ueid();
  static const int kUEIDFieldNumber = 3;
  const ::std::string& ueid() const;
  void set_ueid(const ::std::string& value);
  #if LANG_CXX11
  void set_ueid(::std::string&& value);
  #endif
  void set_ueid(const char* value);
  void set_ueid(const char* value, size_t size);
  ::std::string* mutable_ueid();
  ::std::string* release_ueid();
  void set_allocated_ueid(::std::string* ueid);

  // int64 ControlStyle = 1;
  void clear_controlstyle();
  static const int kControlStyleFieldNumber = 1;
  ::google::protobuf::int64 controlstyle() const;
  void set_controlstyle(::google::protobuf::int64 value);

  // int64 ControlActionId = 2;
  void clear_controlactionid();
  static const int kControlActionIdFieldNumber = 2;
  ::google::protobuf::int64 controlactionid() const;
  void set_controlactionid(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:api.RICControlHeader)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr ueid_;
  ::google::protobuf::int64 controlstyle_;
  ::google::protobuf::int64 controlactionid_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_api_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class RICControlMessage : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:api.RICControlMessage) */ {
 public:
  RICControlMessage();
  virtual ~RICControlMessage();

  RICControlMessage(const RICControlMessage& from);

  inline RICControlMessage& operator=(const RICControlMessage& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  RICControlMessage(RICControlMessage&& from) noexcept
    : RICControlMessage() {
    *this = ::std::move(from);
  }

  inline RICControlMessage& operator=(RICControlMessage&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor();
  static const RICControlMessage& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const RICControlMessage* internal_default_instance() {
    return reinterpret_cast<const RICControlMessage*>(
               &_RICControlMessage_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    2;

  void Swap(RICControlMessage* other);
  friend void swap(RICControlMessage& a, RICControlMessage& b) {
    a.Swap(&b);
  }

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

  inline RICControlMessage* New() const final {
    return CreateMaybeMessage<RICControlMessage>(NULL);
  }

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RICControlMessage* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // string TargetCellID = 2;
  void clear_targetcellid();
  static const int kTargetCellIDFieldNumber = 2;
  const ::std::string& targetcellid() const;
  void set_targetcellid(const ::std::string& value);
  #if LANG_CXX11
  void set_targetcellid(::std::string&& value);
  #endif
  void set_targetcellid(const char* value);
  void set_targetcellid(const char* value, size_t size);
  ::std::string* mutable_targetcellid();
  ::std::string* release_targetcellid();
  void set_allocated_targetcellid(::std::string* targetcellid);

  // .api.RICControlCellTypeEnum RICControlCellTypeVal = 1;
  void clear_riccontrolcelltypeval();
  static const int kRICControlCellTypeValFieldNumber = 1;
  ::api::RICControlCellTypeEnum riccontrolcelltypeval() const;
  void set_riccontrolcelltypeval(::api::RICControlCellTypeEnum value);

  // @@protoc_insertion_point(class_scope:api.RICControlMessage)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr targetcellid_;
  int riccontrolcelltypeval_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_api_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class RicControlGrpcReq : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:api.RicControlGrpcReq) */ {
 public:
  RicControlGrpcReq();
  virtual ~RicControlGrpcReq();

  RicControlGrpcReq(const RicControlGrpcReq& from);

  inline RicControlGrpcReq& operator=(const RicControlGrpcReq& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  RicControlGrpcReq(RicControlGrpcReq&& from) noexcept
    : RicControlGrpcReq() {
    *this = ::std::move(from);
  }

  inline RicControlGrpcReq& operator=(RicControlGrpcReq&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor();
  static const RicControlGrpcReq& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const RicControlGrpcReq* internal_default_instance() {
    return reinterpret_cast<const RicControlGrpcReq*>(
               &_RicControlGrpcReq_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    3;

  void Swap(RicControlGrpcReq* other);
  friend void swap(RicControlGrpcReq& a, RicControlGrpcReq& b) {
    a.Swap(&b);
  }

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

  inline RicControlGrpcReq* New() const final {
    return CreateMaybeMessage<RicControlGrpcReq>(NULL);
  }

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RicControlGrpcReq* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // string e2NodeID = 1;
  void clear_e2nodeid();
  static const int kE2NodeIDFieldNumber = 1;
  const ::std::string& e2nodeid() const;
  void set_e2nodeid(const ::std::string& value);
  #if LANG_CXX11
  void set_e2nodeid(::std::string&& value);
  #endif
  void set_e2nodeid(const char* value);
  void set_e2nodeid(const char* value, size_t size);
  ::std::string* mutable_e2nodeid();
  ::std::string* release_e2nodeid();
  void set_allocated_e2nodeid(::std::string* e2nodeid);

  // string plmnID = 2;
  void clear_plmnid();
  static const int kPlmnIDFieldNumber = 2;
  const ::std::string& plmnid() const;
  void set_plmnid(const ::std::string& value);
  #if LANG_CXX11
  void set_plmnid(::std::string&& value);
  #endif
  void set_plmnid(const char* value);
  void set_plmnid(const char* value, size_t size);
  ::std::string* mutable_plmnid();
  ::std::string* release_plmnid();
  void set_allocated_plmnid(::std::string* plmnid);

  // string ranName = 3;
  void clear_ranname();
  static const int kRanNameFieldNumber = 3;
  const ::std::string& ranname() const;
  void set_ranname(const ::std::string& value);
  #if LANG_CXX11
  void set_ranname(::std::string&& value);
  #endif
  void set_ranname(const char* value);
  void set_ranname(const char* value, size_t size);
  ::std::string* mutable_ranname();
  ::std::string* release_ranname();
  void set_allocated_ranname(::std::string* ranname);

  // .api.RICE2APHeader RICE2APHeaderData = 4;
  bool has_rice2apheaderdata() const;
  void clear_rice2apheaderdata();
  static const int kRICE2APHeaderDataFieldNumber = 4;
  private:
  const ::api::RICE2APHeader& _internal_rice2apheaderdata() const;
  public:
  const ::api::RICE2APHeader& rice2apheaderdata() const;
  ::api::RICE2APHeader* release_rice2apheaderdata();
  ::api::RICE2APHeader* mutable_rice2apheaderdata();
  void set_allocated_rice2apheaderdata(::api::RICE2APHeader* rice2apheaderdata);

  // .api.RICControlHeader RICControlHeaderData = 5;
  bool has_riccontrolheaderdata() const;
  void clear_riccontrolheaderdata();
  static const int kRICControlHeaderDataFieldNumber = 5;
  private:
  const ::api::RICControlHeader& _internal_riccontrolheaderdata() const;
  public:
  const ::api::RICControlHeader& riccontrolheaderdata() const;
  ::api::RICControlHeader* release_riccontrolheaderdata();
  ::api::RICControlHeader* mutable_riccontrolheaderdata();
  void set_allocated_riccontrolheaderdata(::api::RICControlHeader* riccontrolheaderdata);

  // .api.RICControlMessage RICControlMessageData = 6;
  bool has_riccontrolmessagedata() const;
  void clear_riccontrolmessagedata();
  static const int kRICControlMessageDataFieldNumber = 6;
  private:
  const ::api::RICControlMessage& _internal_riccontrolmessagedata() const;
  public:
  const ::api::RICControlMessage& riccontrolmessagedata() const;
  ::api::RICControlMessage* release_riccontrolmessagedata();
  ::api::RICControlMessage* mutable_riccontrolmessagedata();
  void set_allocated_riccontrolmessagedata(::api::RICControlMessage* riccontrolmessagedata);

  // .api.RICControlAckEnum RICControlAckReqVal = 7;
  void clear_riccontrolackreqval();
  static const int kRICControlAckReqValFieldNumber = 7;
  ::api::RICControlAckEnum riccontrolackreqval() const;
  void set_riccontrolackreqval(::api::RICControlAckEnum value);

  // @@protoc_insertion_point(class_scope:api.RicControlGrpcReq)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr e2nodeid_;
  ::google::protobuf::internal::ArenaStringPtr plmnid_;
  ::google::protobuf::internal::ArenaStringPtr ranname_;
  ::api::RICE2APHeader* rice2apheaderdata_;
  ::api::RICControlHeader* riccontrolheaderdata_;
  ::api::RICControlMessage* riccontrolmessagedata_;
  int riccontrolackreqval_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_api_2eproto::TableStruct;
};
// -------------------------------------------------------------------

class RicControlGrpcRsp : public ::google::protobuf::Message /* @@protoc_insertion_point(class_definition:api.RicControlGrpcRsp) */ {
 public:
  RicControlGrpcRsp();
  virtual ~RicControlGrpcRsp();

  RicControlGrpcRsp(const RicControlGrpcRsp& from);

  inline RicControlGrpcRsp& operator=(const RicControlGrpcRsp& from) {
    CopyFrom(from);
    return *this;
  }
  #if LANG_CXX11
  RicControlGrpcRsp(RicControlGrpcRsp&& from) noexcept
    : RicControlGrpcRsp() {
    *this = ::std::move(from);
  }

  inline RicControlGrpcRsp& operator=(RicControlGrpcRsp&& from) noexcept {
    if (GetArenaNoVirtual() == from.GetArenaNoVirtual()) {
      if (this != &from) InternalSwap(&from);
    } else {
      CopyFrom(from);
    }
    return *this;
  }
  #endif
  static const ::google::protobuf::Descriptor* descriptor();
  static const RicControlGrpcRsp& default_instance();

  static void InitAsDefaultInstance();  // FOR INTERNAL USE ONLY
  static inline const RicControlGrpcRsp* internal_default_instance() {
    return reinterpret_cast<const RicControlGrpcRsp*>(
               &_RicControlGrpcRsp_default_instance_);
  }
  static constexpr int kIndexInFileMessages =
    4;

  void Swap(RicControlGrpcRsp* other);
  friend void swap(RicControlGrpcRsp& a, RicControlGrpcRsp& b) {
    a.Swap(&b);
  }

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

  inline RicControlGrpcRsp* New() const final {
    return CreateMaybeMessage<RicControlGrpcRsp>(NULL);
  }

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

  size_t ByteSizeLong() const final;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) final;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const final;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const final;
  int GetCachedSize() const final { return _cached_size_.Get(); }

  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const final;
  void InternalSwap(RicControlGrpcRsp* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

  ::google::protobuf::Metadata GetMetadata() const final;

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

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

  // string description = 2;
  void clear_description();
  static const int kDescriptionFieldNumber = 2;
  const ::std::string& description() const;
  void set_description(const ::std::string& value);
  #if LANG_CXX11
  void set_description(::std::string&& value);
  #endif
  void set_description(const char* value);
  void set_description(const char* value, size_t size);
  ::std::string* mutable_description();
  ::std::string* release_description();
  void set_allocated_description(::std::string* description);

  // int32 rspCode = 1;
  void clear_rspcode();
  static const int kRspCodeFieldNumber = 1;
  ::google::protobuf::int32 rspcode() const;
  void set_rspcode(::google::protobuf::int32 value);

  // @@protoc_insertion_point(class_scope:api.RicControlGrpcRsp)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::ArenaStringPtr description_;
  ::google::protobuf::int32 rspcode_;
  mutable ::google::protobuf::internal::CachedSize _cached_size_;
  friend struct ::protobuf_api_2eproto::TableStruct;
};
// ===================================================================


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

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

// int64 RanFuncId = 1;
inline void RICE2APHeader::clear_ranfuncid() {
  ranfuncid_ = GOOGLE_LONGLONG(0);
}
inline ::google::protobuf::int64 RICE2APHeader::ranfuncid() const {
  // @@protoc_insertion_point(field_get:api.RICE2APHeader.RanFuncId)
  return ranfuncid_;
}
inline void RICE2APHeader::set_ranfuncid(::google::protobuf::int64 value) {

  ranfuncid_ = value;
  // @@protoc_insertion_point(field_set:api.RICE2APHeader.RanFuncId)
}

// int64 RICRequestorID = 2;
inline void RICE2APHeader::clear_ricrequestorid() {
  ricrequestorid_ = GOOGLE_LONGLONG(0);
}
inline ::google::protobuf::int64 RICE2APHeader::ricrequestorid() const {
  // @@protoc_insertion_point(field_get:api.RICE2APHeader.RICRequestorID)
  return ricrequestorid_;
}
inline void RICE2APHeader::set_ricrequestorid(::google::protobuf::int64 value) {

  ricrequestorid_ = value;
  // @@protoc_insertion_point(field_set:api.RICE2APHeader.RICRequestorID)
}

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

// RICControlHeader

// int64 ControlStyle = 1;
inline void RICControlHeader::clear_controlstyle() {
  controlstyle_ = GOOGLE_LONGLONG(0);
}
inline ::google::protobuf::int64 RICControlHeader::controlstyle() const {
  // @@protoc_insertion_point(field_get:api.RICControlHeader.ControlStyle)
  return controlstyle_;
}
inline void RICControlHeader::set_controlstyle(::google::protobuf::int64 value) {

  controlstyle_ = value;
  // @@protoc_insertion_point(field_set:api.RICControlHeader.ControlStyle)
}

// int64 ControlActionId = 2;
inline void RICControlHeader::clear_controlactionid() {
  controlactionid_ = GOOGLE_LONGLONG(0);
}
inline ::google::protobuf::int64 RICControlHeader::controlactionid() const {
  // @@protoc_insertion_point(field_get:api.RICControlHeader.ControlActionId)
  return controlactionid_;
}
inline void RICControlHeader::set_controlactionid(::google::protobuf::int64 value) {

  controlactionid_ = value;
  // @@protoc_insertion_point(field_set:api.RICControlHeader.ControlActionId)
}

// string UEID = 3;
inline void RICControlHeader::clear_ueid() {
  ueid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& RICControlHeader::ueid() const {
  // @@protoc_insertion_point(field_get:api.RICControlHeader.UEID)
  return ueid_.GetNoArena();
}
inline void RICControlHeader::set_ueid(const ::std::string& value) {

  ueid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:api.RICControlHeader.UEID)
}
#if LANG_CXX11
inline void RICControlHeader::set_ueid(::std::string&& value) {

  ueid_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:api.RICControlHeader.UEID)
}
#endif
inline void RICControlHeader::set_ueid(const char* value) {
  GOOGLE_DCHECK(value != NULL);

  ueid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:api.RICControlHeader.UEID)
}
inline void RICControlHeader::set_ueid(const char* value, size_t size) {

  ueid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:api.RICControlHeader.UEID)
}
inline ::std::string* RICControlHeader::mutable_ueid() {

  // @@protoc_insertion_point(field_mutable:api.RICControlHeader.UEID)
  return ueid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* RICControlHeader::release_ueid() {
  // @@protoc_insertion_point(field_release:api.RICControlHeader.UEID)

  return ueid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void RICControlHeader::set_allocated_ueid(::std::string* ueid) {
  if (ueid != NULL) {

  } else {

  }
  ueid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ueid);
  // @@protoc_insertion_point(field_set_allocated:api.RICControlHeader.UEID)
}

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

// RICControlMessage

// .api.RICControlCellTypeEnum RICControlCellTypeVal = 1;
inline void RICControlMessage::clear_riccontrolcelltypeval() {
  riccontrolcelltypeval_ = 0;
}
inline ::api::RICControlCellTypeEnum RICControlMessage::riccontrolcelltypeval() const {
  // @@protoc_insertion_point(field_get:api.RICControlMessage.RICControlCellTypeVal)
  return static_cast< ::api::RICControlCellTypeEnum >(riccontrolcelltypeval_);
}
inline void RICControlMessage::set_riccontrolcelltypeval(::api::RICControlCellTypeEnum value) {

  riccontrolcelltypeval_ = value;
  // @@protoc_insertion_point(field_set:api.RICControlMessage.RICControlCellTypeVal)
}

// string TargetCellID = 2;
inline void RICControlMessage::clear_targetcellid() {
  targetcellid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& RICControlMessage::targetcellid() const {
  // @@protoc_insertion_point(field_get:api.RICControlMessage.TargetCellID)
  return targetcellid_.GetNoArena();
}
inline void RICControlMessage::set_targetcellid(const ::std::string& value) {

  targetcellid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:api.RICControlMessage.TargetCellID)
}
#if LANG_CXX11
inline void RICControlMessage::set_targetcellid(::std::string&& value) {

  targetcellid_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:api.RICControlMessage.TargetCellID)
}
#endif
inline void RICControlMessage::set_targetcellid(const char* value) {
  GOOGLE_DCHECK(value != NULL);

  targetcellid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:api.RICControlMessage.TargetCellID)
}
inline void RICControlMessage::set_targetcellid(const char* value, size_t size) {

  targetcellid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:api.RICControlMessage.TargetCellID)
}
inline ::std::string* RICControlMessage::mutable_targetcellid() {

  // @@protoc_insertion_point(field_mutable:api.RICControlMessage.TargetCellID)
  return targetcellid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* RICControlMessage::release_targetcellid() {
  // @@protoc_insertion_point(field_release:api.RICControlMessage.TargetCellID)

  return targetcellid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void RICControlMessage::set_allocated_targetcellid(::std::string* targetcellid) {
  if (targetcellid != NULL) {

  } else {

  }
  targetcellid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), targetcellid);
  // @@protoc_insertion_point(field_set_allocated:api.RICControlMessage.TargetCellID)
}

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

// RicControlGrpcReq

// string e2NodeID = 1;
inline void RicControlGrpcReq::clear_e2nodeid() {
  e2nodeid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& RicControlGrpcReq::e2nodeid() const {
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.e2NodeID)
  return e2nodeid_.GetNoArena();
}
inline void RicControlGrpcReq::set_e2nodeid(const ::std::string& value) {

  e2nodeid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:api.RicControlGrpcReq.e2NodeID)
}
#if LANG_CXX11
inline void RicControlGrpcReq::set_e2nodeid(::std::string&& value) {

  e2nodeid_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:api.RicControlGrpcReq.e2NodeID)
}
#endif
inline void RicControlGrpcReq::set_e2nodeid(const char* value) {
  GOOGLE_DCHECK(value != NULL);

  e2nodeid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:api.RicControlGrpcReq.e2NodeID)
}
inline void RicControlGrpcReq::set_e2nodeid(const char* value, size_t size) {

  e2nodeid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:api.RicControlGrpcReq.e2NodeID)
}
inline ::std::string* RicControlGrpcReq::mutable_e2nodeid() {

  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcReq.e2NodeID)
  return e2nodeid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* RicControlGrpcReq::release_e2nodeid() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcReq.e2NodeID)

  return e2nodeid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void RicControlGrpcReq::set_allocated_e2nodeid(::std::string* e2nodeid) {
  if (e2nodeid != NULL) {

  } else {

  }
  e2nodeid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), e2nodeid);
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcReq.e2NodeID)
}

// string plmnID = 2;
inline void RicControlGrpcReq::clear_plmnid() {
  plmnid_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& RicControlGrpcReq::plmnid() const {
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.plmnID)
  return plmnid_.GetNoArena();
}
inline void RicControlGrpcReq::set_plmnid(const ::std::string& value) {

  plmnid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:api.RicControlGrpcReq.plmnID)
}
#if LANG_CXX11
inline void RicControlGrpcReq::set_plmnid(::std::string&& value) {

  plmnid_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:api.RicControlGrpcReq.plmnID)
}
#endif
inline void RicControlGrpcReq::set_plmnid(const char* value) {
  GOOGLE_DCHECK(value != NULL);

  plmnid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:api.RicControlGrpcReq.plmnID)
}
inline void RicControlGrpcReq::set_plmnid(const char* value, size_t size) {

  plmnid_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:api.RicControlGrpcReq.plmnID)
}
inline ::std::string* RicControlGrpcReq::mutable_plmnid() {

  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcReq.plmnID)
  return plmnid_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* RicControlGrpcReq::release_plmnid() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcReq.plmnID)

  return plmnid_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void RicControlGrpcReq::set_allocated_plmnid(::std::string* plmnid) {
  if (plmnid != NULL) {

  } else {

  }
  plmnid_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), plmnid);
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcReq.plmnID)
}

// string ranName = 3;
inline void RicControlGrpcReq::clear_ranname() {
  ranname_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& RicControlGrpcReq::ranname() const {
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.ranName)
  return ranname_.GetNoArena();
}
inline void RicControlGrpcReq::set_ranname(const ::std::string& value) {

  ranname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:api.RicControlGrpcReq.ranName)
}
#if LANG_CXX11
inline void RicControlGrpcReq::set_ranname(::std::string&& value) {

  ranname_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:api.RicControlGrpcReq.ranName)
}
#endif
inline void RicControlGrpcReq::set_ranname(const char* value) {
  GOOGLE_DCHECK(value != NULL);

  ranname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:api.RicControlGrpcReq.ranName)
}
inline void RicControlGrpcReq::set_ranname(const char* value, size_t size) {

  ranname_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:api.RicControlGrpcReq.ranName)
}
inline ::std::string* RicControlGrpcReq::mutable_ranname() {

  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcReq.ranName)
  return ranname_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* RicControlGrpcReq::release_ranname() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcReq.ranName)

  return ranname_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void RicControlGrpcReq::set_allocated_ranname(::std::string* ranname) {
  if (ranname != NULL) {

  } else {

  }
  ranname_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ranname);
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcReq.ranName)
}

// .api.RICE2APHeader RICE2APHeaderData = 4;
inline bool RicControlGrpcReq::has_rice2apheaderdata() const {
  return this != internal_default_instance() && rice2apheaderdata_ != NULL;
}
inline void RicControlGrpcReq::clear_rice2apheaderdata() {
  if (GetArenaNoVirtual() == NULL && rice2apheaderdata_ != NULL) {
    delete rice2apheaderdata_;
  }
  rice2apheaderdata_ = NULL;
}
inline const ::api::RICE2APHeader& RicControlGrpcReq::_internal_rice2apheaderdata() const {
  return *rice2apheaderdata_;
}
inline const ::api::RICE2APHeader& RicControlGrpcReq::rice2apheaderdata() const {
  const ::api::RICE2APHeader* p = rice2apheaderdata_;
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.RICE2APHeaderData)
  return p != NULL ? *p : *reinterpret_cast<const ::api::RICE2APHeader*>(
      &::api::_RICE2APHeader_default_instance_);
}
inline ::api::RICE2APHeader* RicControlGrpcReq::release_rice2apheaderdata() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcReq.RICE2APHeaderData)

  ::api::RICE2APHeader* temp = rice2apheaderdata_;
  rice2apheaderdata_ = NULL;
  return temp;
}
inline ::api::RICE2APHeader* RicControlGrpcReq::mutable_rice2apheaderdata() {

  if (rice2apheaderdata_ == NULL) {
    auto* p = CreateMaybeMessage<::api::RICE2APHeader>(GetArenaNoVirtual());
    rice2apheaderdata_ = p;
  }
  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcReq.RICE2APHeaderData)
  return rice2apheaderdata_;
}
inline void RicControlGrpcReq::set_allocated_rice2apheaderdata(::api::RICE2APHeader* rice2apheaderdata) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete rice2apheaderdata_;
  }
  if (rice2apheaderdata) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      rice2apheaderdata = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, rice2apheaderdata, submessage_arena);
    }

  } else {

  }
  rice2apheaderdata_ = rice2apheaderdata;
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcReq.RICE2APHeaderData)
}

// .api.RICControlHeader RICControlHeaderData = 5;
inline bool RicControlGrpcReq::has_riccontrolheaderdata() const {
  return this != internal_default_instance() && riccontrolheaderdata_ != NULL;
}
inline void RicControlGrpcReq::clear_riccontrolheaderdata() {
  if (GetArenaNoVirtual() == NULL && riccontrolheaderdata_ != NULL) {
    delete riccontrolheaderdata_;
  }
  riccontrolheaderdata_ = NULL;
}
inline const ::api::RICControlHeader& RicControlGrpcReq::_internal_riccontrolheaderdata() const {
  return *riccontrolheaderdata_;
}
inline const ::api::RICControlHeader& RicControlGrpcReq::riccontrolheaderdata() const {
  const ::api::RICControlHeader* p = riccontrolheaderdata_;
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.RICControlHeaderData)
  return p != NULL ? *p : *reinterpret_cast<const ::api::RICControlHeader*>(
      &::api::_RICControlHeader_default_instance_);
}
inline ::api::RICControlHeader* RicControlGrpcReq::release_riccontrolheaderdata() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcReq.RICControlHeaderData)

  ::api::RICControlHeader* temp = riccontrolheaderdata_;
  riccontrolheaderdata_ = NULL;
  return temp;
}
inline ::api::RICControlHeader* RicControlGrpcReq::mutable_riccontrolheaderdata() {

  if (riccontrolheaderdata_ == NULL) {
    auto* p = CreateMaybeMessage<::api::RICControlHeader>(GetArenaNoVirtual());
    riccontrolheaderdata_ = p;
  }
  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcReq.RICControlHeaderData)
  return riccontrolheaderdata_;
}
inline void RicControlGrpcReq::set_allocated_riccontrolheaderdata(::api::RICControlHeader* riccontrolheaderdata) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete riccontrolheaderdata_;
  }
  if (riccontrolheaderdata) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      riccontrolheaderdata = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, riccontrolheaderdata, submessage_arena);
    }

  } else {

  }
  riccontrolheaderdata_ = riccontrolheaderdata;
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcReq.RICControlHeaderData)
}

// .api.RICControlMessage RICControlMessageData = 6;
inline bool RicControlGrpcReq::has_riccontrolmessagedata() const {
  return this != internal_default_instance() && riccontrolmessagedata_ != NULL;
}
inline void RicControlGrpcReq::clear_riccontrolmessagedata() {
  if (GetArenaNoVirtual() == NULL && riccontrolmessagedata_ != NULL) {
    delete riccontrolmessagedata_;
  }
  riccontrolmessagedata_ = NULL;
}
inline const ::api::RICControlMessage& RicControlGrpcReq::_internal_riccontrolmessagedata() const {
  return *riccontrolmessagedata_;
}
inline const ::api::RICControlMessage& RicControlGrpcReq::riccontrolmessagedata() const {
  const ::api::RICControlMessage* p = riccontrolmessagedata_;
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.RICControlMessageData)
  return p != NULL ? *p : *reinterpret_cast<const ::api::RICControlMessage*>(
      &::api::_RICControlMessage_default_instance_);
}
inline ::api::RICControlMessage* RicControlGrpcReq::release_riccontrolmessagedata() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcReq.RICControlMessageData)

  ::api::RICControlMessage* temp = riccontrolmessagedata_;
  riccontrolmessagedata_ = NULL;
  return temp;
}
inline ::api::RICControlMessage* RicControlGrpcReq::mutable_riccontrolmessagedata() {

  if (riccontrolmessagedata_ == NULL) {
    auto* p = CreateMaybeMessage<::api::RICControlMessage>(GetArenaNoVirtual());
    riccontrolmessagedata_ = p;
  }
  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcReq.RICControlMessageData)
  return riccontrolmessagedata_;
}
inline void RicControlGrpcReq::set_allocated_riccontrolmessagedata(::api::RICControlMessage* riccontrolmessagedata) {
  ::google::protobuf::Arena* message_arena = GetArenaNoVirtual();
  if (message_arena == NULL) {
    delete riccontrolmessagedata_;
  }
  if (riccontrolmessagedata) {
    ::google::protobuf::Arena* submessage_arena = NULL;
    if (message_arena != submessage_arena) {
      riccontrolmessagedata = ::google::protobuf::internal::GetOwnedMessage(
          message_arena, riccontrolmessagedata, submessage_arena);
    }

  } else {

  }
  riccontrolmessagedata_ = riccontrolmessagedata;
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcReq.RICControlMessageData)
}

// .api.RICControlAckEnum RICControlAckReqVal = 7;
inline void RicControlGrpcReq::clear_riccontrolackreqval() {
  riccontrolackreqval_ = 0;
}
inline ::api::RICControlAckEnum RicControlGrpcReq::riccontrolackreqval() const {
  // @@protoc_insertion_point(field_get:api.RicControlGrpcReq.RICControlAckReqVal)
  return static_cast< ::api::RICControlAckEnum >(riccontrolackreqval_);
}
inline void RicControlGrpcReq::set_riccontrolackreqval(::api::RICControlAckEnum value) {

  riccontrolackreqval_ = value;
  // @@protoc_insertion_point(field_set:api.RicControlGrpcReq.RICControlAckReqVal)
}

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

// RicControlGrpcRsp

// int32 rspCode = 1;
inline void RicControlGrpcRsp::clear_rspcode() {
  rspcode_ = 0;
}
inline ::google::protobuf::int32 RicControlGrpcRsp::rspcode() const {
  // @@protoc_insertion_point(field_get:api.RicControlGrpcRsp.rspCode)
  return rspcode_;
}
inline void RicControlGrpcRsp::set_rspcode(::google::protobuf::int32 value) {

  rspcode_ = value;
  // @@protoc_insertion_point(field_set:api.RicControlGrpcRsp.rspCode)
}

// string description = 2;
inline void RicControlGrpcRsp::clear_description() {
  description_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline const ::std::string& RicControlGrpcRsp::description() const {
  // @@protoc_insertion_point(field_get:api.RicControlGrpcRsp.description)
  return description_.GetNoArena();
}
inline void RicControlGrpcRsp::set_description(const ::std::string& value) {

  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:api.RicControlGrpcRsp.description)
}
#if LANG_CXX11
inline void RicControlGrpcRsp::set_description(::std::string&& value) {

  description_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:api.RicControlGrpcRsp.description)
}
#endif
inline void RicControlGrpcRsp::set_description(const char* value) {
  GOOGLE_DCHECK(value != NULL);

  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:api.RicControlGrpcRsp.description)
}
inline void RicControlGrpcRsp::set_description(const char* value, size_t size) {

  description_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:api.RicControlGrpcRsp.description)
}
inline ::std::string* RicControlGrpcRsp::mutable_description() {

  // @@protoc_insertion_point(field_mutable:api.RicControlGrpcRsp.description)
  return description_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* RicControlGrpcRsp::release_description() {
  // @@protoc_insertion_point(field_release:api.RicControlGrpcRsp.description)

  return description_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void RicControlGrpcRsp::set_allocated_description(::std::string* description) {
  if (description != NULL) {

  } else {

  }
  description_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), description);
  // @@protoc_insertion_point(field_set_allocated:api.RicControlGrpcRsp.description)
}

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

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

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

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


// @@protoc_insertion_point(namespace_scope)

}  // namespace api

namespace google {
namespace protobuf {

template <> struct is_proto_enum< ::api::RICControlCellTypeEnum> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::api::RICControlCellTypeEnum>() {
  return ::api::RICControlCellTypeEnum_descriptor();
}
template <> struct is_proto_enum< ::api::RICControlAckEnum> : ::std::true_type {};
template <>
inline const EnumDescriptor* GetEnumDescriptor< ::api::RICControlAckEnum>() {
  return ::api::RICControlAckEnum_descriptor();
}

}  // namespace protobuf
}  // namespace google

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_INCLUDED_api_2eproto
