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

#define INTERNAL_SUPPRESS_PROTOBUF_FIELD_DEPRECATION
#include "google_streaming_api.pb.h"

#include <algorithm>

#include <google/protobuf/stubs/common.h>
#include <google/protobuf/stubs/port.h>
#include <google/protobuf/stubs/once.h>
#include <google/protobuf/io/coded_stream.h>
#include <google/protobuf/wire_format_lite_inl.h>
#include <google/protobuf/io/zero_copy_stream_impl_lite.h>
// @@protoc_insertion_point(includes)

namespace cobalt {
namespace speech {
namespace proto {

void protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto() {
  delete SpeechRecognitionEvent::default_instance_;
  delete SpeechRecognitionResult::default_instance_;
  delete SpeechRecognitionAlternative::default_instance_;
}

#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto_impl() {
  GOOGLE_PROTOBUF_VERIFY_VERSION;

#else
void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto() {
  static bool already_here = false;
  if (already_here) return;
  already_here = true;
  GOOGLE_PROTOBUF_VERIFY_VERSION;

#endif
  SpeechRecognitionEvent::default_instance_ = new SpeechRecognitionEvent();
  SpeechRecognitionResult::default_instance_ = new SpeechRecognitionResult();
  SpeechRecognitionAlternative::default_instance_ = new SpeechRecognitionAlternative();
  SpeechRecognitionEvent::default_instance_->InitAsDefaultInstance();
  SpeechRecognitionResult::default_instance_->InitAsDefaultInstance();
  SpeechRecognitionAlternative::default_instance_->InitAsDefaultInstance();
  ::google::protobuf::internal::OnShutdown(&protobuf_ShutdownFile_google_5fstreaming_5fapi_2eproto);
}

#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
GOOGLE_PROTOBUF_DECLARE_ONCE(protobuf_AddDesc_google_5fstreaming_5fapi_2eproto_once_);
void protobuf_AddDesc_google_5fstreaming_5fapi_2eproto() {
  ::google::protobuf::GoogleOnceInit(&protobuf_AddDesc_google_5fstreaming_5fapi_2eproto_once_,
                 &protobuf_AddDesc_google_5fstreaming_5fapi_2eproto_impl);
}
#else
// Force AddDescriptors() to be called at static initialization time.
struct StaticDescriptorInitializer_google_5fstreaming_5fapi_2eproto {
  StaticDescriptorInitializer_google_5fstreaming_5fapi_2eproto() {
    protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
  }
} static_descriptor_initializer_google_5fstreaming_5fapi_2eproto_;
#endif

namespace {

static void MergeFromFail(int line) GOOGLE_ATTRIBUTE_COLD;
GOOGLE_ATTRIBUTE_NOINLINE static void MergeFromFail(int line) {
  GOOGLE_CHECK(false) << __FILE__ << ":" << line;
}

}  // namespace


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

static ::std::string* MutableUnknownFieldsForSpeechRecognitionEvent(
    SpeechRecognitionEvent* ptr) {
  return ptr->mutable_unknown_fields();
}

bool SpeechRecognitionEvent_StatusCode_IsValid(int value) {
  switch(value) {
    case 0:
    case 1:
    case 2:
    case 3:
    case 4:
    case 5:
    case 6:
    case 7:
    case 8:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_SUCCESS;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_NO_SPEECH;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_ABORTED;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_AUDIO_CAPTURE;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_NETWORK;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_NOT_ALLOWED;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_SERVICE_NOT_ALLOWED;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_BAD_GRAMMAR;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::STATUS_LANGUAGE_NOT_SUPPORTED;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::StatusCode_MIN;
const SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::StatusCode_MAX;
const int SpeechRecognitionEvent::StatusCode_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
bool SpeechRecognitionEvent_EndpointerEventType_IsValid(int value) {
  switch(value) {
    case 0:
    case 1:
    case 2:
    case 3:
      return true;
    default:
      return false;
  }
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::START_OF_SPEECH;
const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::END_OF_SPEECH;
const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::END_OF_AUDIO;
const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::END_OF_UTTERANCE;
const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::EndpointerEventType_MIN;
const SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::EndpointerEventType_MAX;
const int SpeechRecognitionEvent::EndpointerEventType_ARRAYSIZE;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900
#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SpeechRecognitionEvent::kStatusFieldNumber;
const int SpeechRecognitionEvent::kResultFieldNumber;
const int SpeechRecognitionEvent::kEndpointFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SpeechRecognitionEvent::SpeechRecognitionEvent()
  : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:cobalt.speech.proto.SpeechRecognitionEvent)
}

void SpeechRecognitionEvent::InitAsDefaultInstance() {
}

SpeechRecognitionEvent::SpeechRecognitionEvent(const SpeechRecognitionEvent& from)
  : ::google::protobuf::MessageLite(),
    _arena_ptr_(NULL) {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:cobalt.speech.proto.SpeechRecognitionEvent)
}

void SpeechRecognitionEvent::SharedCtor() {
  ::google::protobuf::internal::GetEmptyString();
  _cached_size_ = 0;
  _unknown_fields_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  status_ = 0;
  endpoint_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

SpeechRecognitionEvent::~SpeechRecognitionEvent() {
  // @@protoc_insertion_point(destructor:cobalt.speech.proto.SpeechRecognitionEvent)
  SharedDtor();
}

void SpeechRecognitionEvent::SharedDtor() {
  _unknown_fields_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  if (this != &default_instance()) {
  #else
  if (this != default_instance_) {
  #endif
  }
}

void SpeechRecognitionEvent::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const SpeechRecognitionEvent& SpeechRecognitionEvent::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
#else
  if (default_instance_ == NULL) protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
#endif
  return *default_instance_;
}

SpeechRecognitionEvent* SpeechRecognitionEvent::default_instance_ = NULL;

SpeechRecognitionEvent* SpeechRecognitionEvent::New(::google::protobuf::Arena* arena) const {
  SpeechRecognitionEvent* n = new SpeechRecognitionEvent;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void SpeechRecognitionEvent::Clear() {
// @@protoc_insertion_point(message_clear_start:cobalt.speech.proto.SpeechRecognitionEvent)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(SpeechRecognitionEvent, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<SpeechRecognitionEvent*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

  ZR_(status_, endpoint_);

#undef ZR_HELPER_
#undef ZR_

  result_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  _unknown_fields_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

bool SpeechRecognitionEvent::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(
      ::google::protobuf::internal::NewPermanentCallback(
          &MutableUnknownFieldsForSpeechRecognitionEvent, this));
  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
      &unknown_fields_string, false);
  // @@protoc_insertion_point(parse_start:cobalt.speech.proto.SpeechRecognitionEvent)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
      case 1: {
        if (tag == 8) {
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode_IsValid(value)) {
            set_status(static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode >(value));
          } else {
            unknown_fields_stream.WriteVarint32(8);
            unknown_fields_stream.WriteVarint32(value);
          }
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(18)) goto parse_result;
        break;
      }

      // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
      case 2: {
        if (tag == 18) {
         parse_result:
          DO_(input->IncrementRecursionDepth());
         parse_loop_result:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
                input, add_result()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(18)) goto parse_loop_result;
        input->UnsafeDecrementRecursionDepth();
        if (input->ExpectTag(32)) goto parse_endpoint;
        break;
      }

      // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
      case 4: {
        if (tag == 32) {
         parse_endpoint:
          int value;
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   int, ::google::protobuf::internal::WireFormatLite::TYPE_ENUM>(
                 input, &value)));
          if (::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType_IsValid(value)) {
            set_endpoint(static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType >(value));
          } else {
            unknown_fields_stream.WriteVarint32(32);
            unknown_fields_stream.WriteVarint32(value);
          }
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
            input, tag, &unknown_fields_stream));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:cobalt.speech.proto.SpeechRecognitionEvent)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:cobalt.speech.proto.SpeechRecognitionEvent)
  return false;
#undef DO_
}

void SpeechRecognitionEvent::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:cobalt.speech.proto.SpeechRecognitionEvent)
  // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
  if (has_status()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      1, this->status(), output);
  }

  // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
  for (unsigned int i = 0, n = this->result_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessage(
      2, this->result(i), output);
  }

  // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
  if (has_endpoint()) {
    ::google::protobuf::internal::WireFormatLite::WriteEnum(
      4, this->endpoint(), output);
  }

  output->WriteRaw(unknown_fields().data(),
                   static_cast<int>(unknown_fields().size()));
  // @@protoc_insertion_point(serialize_end:cobalt.speech.proto.SpeechRecognitionEvent)
}

int SpeechRecognitionEvent::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:cobalt.speech.proto.SpeechRecognitionEvent)
  int total_size = 0;

  if (_has_bits_[0 / 32] & 5u) {
    // optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
    if (has_status()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->status());
    }

    // optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
    if (has_endpoint()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::EnumSize(this->endpoint());
    }

  }
  // repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
  total_size += 1 * this->result_size();
  for (int i = 0; i < this->result_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->result(i));
  }

  total_size += unknown_fields().size();

  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void SpeechRecognitionEvent::CheckTypeAndMergeFrom(
    const ::google::protobuf::MessageLite& from) {
  MergeFrom(*::google::protobuf::down_cast<const SpeechRecognitionEvent*>(&from));
}

void SpeechRecognitionEvent::MergeFrom(const SpeechRecognitionEvent& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:cobalt.speech.proto.SpeechRecognitionEvent)
  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
  result_.MergeFrom(from.result_);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_status()) {
      set_status(from.status());
    }
    if (from.has_endpoint()) {
      set_endpoint(from.endpoint());
    }
  }
  if (!from.unknown_fields().empty()) {
    mutable_unknown_fields()->append(from.unknown_fields());
  }
}

void SpeechRecognitionEvent::CopyFrom(const SpeechRecognitionEvent& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:cobalt.speech.proto.SpeechRecognitionEvent)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SpeechRecognitionEvent::IsInitialized() const {

  return true;
}

void SpeechRecognitionEvent::Swap(SpeechRecognitionEvent* other) {
  if (other == this) return;
  InternalSwap(other);
}
void SpeechRecognitionEvent::InternalSwap(SpeechRecognitionEvent* other) {
  std::swap(status_, other->status_);
  result_.UnsafeArenaSwap(&other->result_);
  std::swap(endpoint_, other->endpoint_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _unknown_fields_.Swap(&other->_unknown_fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::std::string SpeechRecognitionEvent::GetTypeName() const {
  return "cobalt.speech.proto.SpeechRecognitionEvent";
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// SpeechRecognitionEvent

// optional .cobalt.speech.proto.SpeechRecognitionEvent.StatusCode status = 1 [default = STATUS_SUCCESS];
bool SpeechRecognitionEvent::has_status() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
void SpeechRecognitionEvent::set_has_status() {
  _has_bits_[0] |= 0x00000001u;
}
void SpeechRecognitionEvent::clear_has_status() {
  _has_bits_[0] &= ~0x00000001u;
}
void SpeechRecognitionEvent::clear_status() {
  status_ = 0;
  clear_has_status();
}
 ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode SpeechRecognitionEvent::status() const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionEvent.status)
  return static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode >(status_);
}
 void SpeechRecognitionEvent::set_status(::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode value) {
  assert(::cobalt::speech::proto::SpeechRecognitionEvent_StatusCode_IsValid(value));
  set_has_status();
  status_ = value;
  // @@protoc_insertion_point(field_set:cobalt.speech.proto.SpeechRecognitionEvent.status)
}

// repeated .cobalt.speech.proto.SpeechRecognitionResult result = 2;
int SpeechRecognitionEvent::result_size() const {
  return result_.size();
}
void SpeechRecognitionEvent::clear_result() {
  result_.Clear();
}
const ::cobalt::speech::proto::SpeechRecognitionResult& SpeechRecognitionEvent::result(int index) const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionEvent.result)
  return result_.Get(index);
}
::cobalt::speech::proto::SpeechRecognitionResult* SpeechRecognitionEvent::mutable_result(int index) {
  // @@protoc_insertion_point(field_mutable:cobalt.speech.proto.SpeechRecognitionEvent.result)
  return result_.Mutable(index);
}
::cobalt::speech::proto::SpeechRecognitionResult* SpeechRecognitionEvent::add_result() {
  // @@protoc_insertion_point(field_add:cobalt.speech.proto.SpeechRecognitionEvent.result)
  return result_.Add();
}
::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult >*
SpeechRecognitionEvent::mutable_result() {
  // @@protoc_insertion_point(field_mutable_list:cobalt.speech.proto.SpeechRecognitionEvent.result)
  return &result_;
}
const ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionResult >&
SpeechRecognitionEvent::result() const {
  // @@protoc_insertion_point(field_list:cobalt.speech.proto.SpeechRecognitionEvent.result)
  return result_;
}

// optional .cobalt.speech.proto.SpeechRecognitionEvent.EndpointerEventType endpoint = 4;
bool SpeechRecognitionEvent::has_endpoint() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
void SpeechRecognitionEvent::set_has_endpoint() {
  _has_bits_[0] |= 0x00000004u;
}
void SpeechRecognitionEvent::clear_has_endpoint() {
  _has_bits_[0] &= ~0x00000004u;
}
void SpeechRecognitionEvent::clear_endpoint() {
  endpoint_ = 0;
  clear_has_endpoint();
}
 ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType SpeechRecognitionEvent::endpoint() const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionEvent.endpoint)
  return static_cast< ::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType >(endpoint_);
}
 void SpeechRecognitionEvent::set_endpoint(::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType value) {
  assert(::cobalt::speech::proto::SpeechRecognitionEvent_EndpointerEventType_IsValid(value));
  set_has_endpoint();
  endpoint_ = value;
  // @@protoc_insertion_point(field_set:cobalt.speech.proto.SpeechRecognitionEvent.endpoint)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

static ::std::string* MutableUnknownFieldsForSpeechRecognitionResult(
    SpeechRecognitionResult* ptr) {
  return ptr->mutable_unknown_fields();
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SpeechRecognitionResult::kAlternativeFieldNumber;
const int SpeechRecognitionResult::kFinalFieldNumber;
const int SpeechRecognitionResult::kStabilityFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SpeechRecognitionResult::SpeechRecognitionResult()
  : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:cobalt.speech.proto.SpeechRecognitionResult)
}

void SpeechRecognitionResult::InitAsDefaultInstance() {
}

SpeechRecognitionResult::SpeechRecognitionResult(const SpeechRecognitionResult& from)
  : ::google::protobuf::MessageLite(),
    _arena_ptr_(NULL) {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:cobalt.speech.proto.SpeechRecognitionResult)
}

void SpeechRecognitionResult::SharedCtor() {
  ::google::protobuf::internal::GetEmptyString();
  _cached_size_ = 0;
  _unknown_fields_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  final_ = false;
  stability_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

SpeechRecognitionResult::~SpeechRecognitionResult() {
  // @@protoc_insertion_point(destructor:cobalt.speech.proto.SpeechRecognitionResult)
  SharedDtor();
}

void SpeechRecognitionResult::SharedDtor() {
  _unknown_fields_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  if (this != &default_instance()) {
  #else
  if (this != default_instance_) {
  #endif
  }
}

void SpeechRecognitionResult::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const SpeechRecognitionResult& SpeechRecognitionResult::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
#else
  if (default_instance_ == NULL) protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
#endif
  return *default_instance_;
}

SpeechRecognitionResult* SpeechRecognitionResult::default_instance_ = NULL;

SpeechRecognitionResult* SpeechRecognitionResult::New(::google::protobuf::Arena* arena) const {
  SpeechRecognitionResult* n = new SpeechRecognitionResult;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void SpeechRecognitionResult::Clear() {
// @@protoc_insertion_point(message_clear_start:cobalt.speech.proto.SpeechRecognitionResult)
#if defined(__clang__)
#define ZR_HELPER_(f) \
  _Pragma("clang diagnostic push") \
  _Pragma("clang diagnostic ignored \"-Winvalid-offsetof\"") \
  __builtin_offsetof(SpeechRecognitionResult, f) \
  _Pragma("clang diagnostic pop")
#else
#define ZR_HELPER_(f) reinterpret_cast<char*>(\
  &reinterpret_cast<SpeechRecognitionResult*>(16)->f)
#endif

#define ZR_(first, last) do {\
  ::memset(&first, 0,\
           ZR_HELPER_(last) - ZR_HELPER_(first) + sizeof(last));\
} while (0)

  ZR_(final_, stability_);

#undef ZR_HELPER_
#undef ZR_

  alternative_.Clear();
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  _unknown_fields_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

bool SpeechRecognitionResult::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(
      ::google::protobuf::internal::NewPermanentCallback(
          &MutableUnknownFieldsForSpeechRecognitionResult, this));
  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
      &unknown_fields_string, false);
  // @@protoc_insertion_point(parse_start:cobalt.speech.proto.SpeechRecognitionResult)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
      case 1: {
        if (tag == 10) {
          DO_(input->IncrementRecursionDepth());
         parse_loop_alternative:
          DO_(::google::protobuf::internal::WireFormatLite::ReadMessageNoVirtualNoRecursionDepth(
                input, add_alternative()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(10)) goto parse_loop_alternative;
        input->UnsafeDecrementRecursionDepth();
        if (input->ExpectTag(16)) goto parse_final;
        break;
      }

      // optional bool final = 2 [default = false];
      case 2: {
        if (tag == 16) {
         parse_final:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   bool, ::google::protobuf::internal::WireFormatLite::TYPE_BOOL>(
                 input, &final_)));
          set_has_final();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(29)) goto parse_stability;
        break;
      }

      // optional float stability = 3;
      case 3: {
        if (tag == 29) {
         parse_stability:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                 input, &stability_)));
          set_has_stability();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
            input, tag, &unknown_fields_stream));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:cobalt.speech.proto.SpeechRecognitionResult)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:cobalt.speech.proto.SpeechRecognitionResult)
  return false;
#undef DO_
}

void SpeechRecognitionResult::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:cobalt.speech.proto.SpeechRecognitionResult)
  // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
  for (unsigned int i = 0, n = this->alternative_size(); i < n; i++) {
    ::google::protobuf::internal::WireFormatLite::WriteMessage(
      1, this->alternative(i), output);
  }

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

  // optional float stability = 3;
  if (has_stability()) {
    ::google::protobuf::internal::WireFormatLite::WriteFloat(3, this->stability(), output);
  }

  output->WriteRaw(unknown_fields().data(),
                   static_cast<int>(unknown_fields().size()));
  // @@protoc_insertion_point(serialize_end:cobalt.speech.proto.SpeechRecognitionResult)
}

int SpeechRecognitionResult::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:cobalt.speech.proto.SpeechRecognitionResult)
  int total_size = 0;

  if (_has_bits_[1 / 32] & 6u) {
    // optional bool final = 2 [default = false];
    if (has_final()) {
      total_size += 1 + 1;
    }

    // optional float stability = 3;
    if (has_stability()) {
      total_size += 1 + 4;
    }

  }
  // repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
  total_size += 1 * this->alternative_size();
  for (int i = 0; i < this->alternative_size(); i++) {
    total_size +=
      ::google::protobuf::internal::WireFormatLite::MessageSizeNoVirtual(
        this->alternative(i));
  }

  total_size += unknown_fields().size();

  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void SpeechRecognitionResult::CheckTypeAndMergeFrom(
    const ::google::protobuf::MessageLite& from) {
  MergeFrom(*::google::protobuf::down_cast<const SpeechRecognitionResult*>(&from));
}

void SpeechRecognitionResult::MergeFrom(const SpeechRecognitionResult& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:cobalt.speech.proto.SpeechRecognitionResult)
  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
  alternative_.MergeFrom(from.alternative_);
  if (from._has_bits_[1 / 32] & (0xffu << (1 % 32))) {
    if (from.has_final()) {
      set_final(from.final());
    }
    if (from.has_stability()) {
      set_stability(from.stability());
    }
  }
  if (!from.unknown_fields().empty()) {
    mutable_unknown_fields()->append(from.unknown_fields());
  }
}

void SpeechRecognitionResult::CopyFrom(const SpeechRecognitionResult& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:cobalt.speech.proto.SpeechRecognitionResult)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SpeechRecognitionResult::IsInitialized() const {

  return true;
}

void SpeechRecognitionResult::Swap(SpeechRecognitionResult* other) {
  if (other == this) return;
  InternalSwap(other);
}
void SpeechRecognitionResult::InternalSwap(SpeechRecognitionResult* other) {
  alternative_.UnsafeArenaSwap(&other->alternative_);
  std::swap(final_, other->final_);
  std::swap(stability_, other->stability_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _unknown_fields_.Swap(&other->_unknown_fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::std::string SpeechRecognitionResult::GetTypeName() const {
  return "cobalt.speech.proto.SpeechRecognitionResult";
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// SpeechRecognitionResult

// repeated .cobalt.speech.proto.SpeechRecognitionAlternative alternative = 1;
int SpeechRecognitionResult::alternative_size() const {
  return alternative_.size();
}
void SpeechRecognitionResult::clear_alternative() {
  alternative_.Clear();
}
const ::cobalt::speech::proto::SpeechRecognitionAlternative& SpeechRecognitionResult::alternative(int index) const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionResult.alternative)
  return alternative_.Get(index);
}
::cobalt::speech::proto::SpeechRecognitionAlternative* SpeechRecognitionResult::mutable_alternative(int index) {
  // @@protoc_insertion_point(field_mutable:cobalt.speech.proto.SpeechRecognitionResult.alternative)
  return alternative_.Mutable(index);
}
::cobalt::speech::proto::SpeechRecognitionAlternative* SpeechRecognitionResult::add_alternative() {
  // @@protoc_insertion_point(field_add:cobalt.speech.proto.SpeechRecognitionResult.alternative)
  return alternative_.Add();
}
::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative >*
SpeechRecognitionResult::mutable_alternative() {
  // @@protoc_insertion_point(field_mutable_list:cobalt.speech.proto.SpeechRecognitionResult.alternative)
  return &alternative_;
}
const ::google::protobuf::RepeatedPtrField< ::cobalt::speech::proto::SpeechRecognitionAlternative >&
SpeechRecognitionResult::alternative() const {
  // @@protoc_insertion_point(field_list:cobalt.speech.proto.SpeechRecognitionResult.alternative)
  return alternative_;
}

// optional bool final = 2 [default = false];
bool SpeechRecognitionResult::has_final() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
void SpeechRecognitionResult::set_has_final() {
  _has_bits_[0] |= 0x00000002u;
}
void SpeechRecognitionResult::clear_has_final() {
  _has_bits_[0] &= ~0x00000002u;
}
void SpeechRecognitionResult::clear_final() {
  final_ = false;
  clear_has_final();
}
 bool SpeechRecognitionResult::final() const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionResult.final)
  return final_;
}
 void SpeechRecognitionResult::set_final(bool value) {
  set_has_final();
  final_ = value;
  // @@protoc_insertion_point(field_set:cobalt.speech.proto.SpeechRecognitionResult.final)
}

// optional float stability = 3;
bool SpeechRecognitionResult::has_stability() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
void SpeechRecognitionResult::set_has_stability() {
  _has_bits_[0] |= 0x00000004u;
}
void SpeechRecognitionResult::clear_has_stability() {
  _has_bits_[0] &= ~0x00000004u;
}
void SpeechRecognitionResult::clear_stability() {
  stability_ = 0;
  clear_has_stability();
}
 float SpeechRecognitionResult::stability() const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionResult.stability)
  return stability_;
}
 void SpeechRecognitionResult::set_stability(float value) {
  set_has_stability();
  stability_ = value;
  // @@protoc_insertion_point(field_set:cobalt.speech.proto.SpeechRecognitionResult.stability)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

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

static ::std::string* MutableUnknownFieldsForSpeechRecognitionAlternative(
    SpeechRecognitionAlternative* ptr) {
  return ptr->mutable_unknown_fields();
}

#if !defined(_MSC_VER) || _MSC_VER >= 1900
const int SpeechRecognitionAlternative::kTranscriptFieldNumber;
const int SpeechRecognitionAlternative::kConfidenceFieldNumber;
#endif  // !defined(_MSC_VER) || _MSC_VER >= 1900

SpeechRecognitionAlternative::SpeechRecognitionAlternative()
  : ::google::protobuf::MessageLite(), _arena_ptr_(NULL) {
  SharedCtor();
  // @@protoc_insertion_point(constructor:cobalt.speech.proto.SpeechRecognitionAlternative)
}

void SpeechRecognitionAlternative::InitAsDefaultInstance() {
}

SpeechRecognitionAlternative::SpeechRecognitionAlternative(const SpeechRecognitionAlternative& from)
  : ::google::protobuf::MessageLite(),
    _arena_ptr_(NULL) {
  SharedCtor();
  MergeFrom(from);
  // @@protoc_insertion_point(copy_constructor:cobalt.speech.proto.SpeechRecognitionAlternative)
}

void SpeechRecognitionAlternative::SharedCtor() {
  ::google::protobuf::internal::GetEmptyString();
  _cached_size_ = 0;
  _unknown_fields_.UnsafeSetDefault(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  transcript_.UnsafeSetDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  confidence_ = 0;
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
}

SpeechRecognitionAlternative::~SpeechRecognitionAlternative() {
  // @@protoc_insertion_point(destructor:cobalt.speech.proto.SpeechRecognitionAlternative)
  SharedDtor();
}

void SpeechRecognitionAlternative::SharedDtor() {
  _unknown_fields_.DestroyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
  transcript_.DestroyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  #ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  if (this != &default_instance()) {
  #else
  if (this != default_instance_) {
  #endif
  }
}

void SpeechRecognitionAlternative::SetCachedSize(int size) const {
  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
}
const SpeechRecognitionAlternative& SpeechRecognitionAlternative::default_instance() {
#ifdef GOOGLE_PROTOBUF_NO_STATIC_INITIALIZER
  protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
#else
  if (default_instance_ == NULL) protobuf_AddDesc_google_5fstreaming_5fapi_2eproto();
#endif
  return *default_instance_;
}

SpeechRecognitionAlternative* SpeechRecognitionAlternative::default_instance_ = NULL;

SpeechRecognitionAlternative* SpeechRecognitionAlternative::New(::google::protobuf::Arena* arena) const {
  SpeechRecognitionAlternative* n = new SpeechRecognitionAlternative;
  if (arena != NULL) {
    arena->Own(n);
  }
  return n;
}

void SpeechRecognitionAlternative::Clear() {
// @@protoc_insertion_point(message_clear_start:cobalt.speech.proto.SpeechRecognitionAlternative)
  if (_has_bits_[0 / 32] & 3u) {
    if (has_transcript()) {
      transcript_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
    }
    confidence_ = 0;
  }
  ::memset(_has_bits_, 0, sizeof(_has_bits_));
  _unknown_fields_.ClearToEmptyNoArena(
      &::google::protobuf::internal::GetEmptyStringAlreadyInited());
}

bool SpeechRecognitionAlternative::MergePartialFromCodedStream(
    ::google::protobuf::io::CodedInputStream* input) {
#define DO_(EXPRESSION) if (!GOOGLE_PREDICT_TRUE(EXPRESSION)) goto failure
  ::google::protobuf::uint32 tag;
  ::google::protobuf::io::LazyStringOutputStream unknown_fields_string(
      ::google::protobuf::internal::NewPermanentCallback(
          &MutableUnknownFieldsForSpeechRecognitionAlternative, this));
  ::google::protobuf::io::CodedOutputStream unknown_fields_stream(
      &unknown_fields_string, false);
  // @@protoc_insertion_point(parse_start:cobalt.speech.proto.SpeechRecognitionAlternative)
  for (;;) {
    ::std::pair< ::google::protobuf::uint32, bool> p = input->ReadTagWithCutoff(127);
    tag = p.first;
    if (!p.second) goto handle_unusual;
    switch (::google::protobuf::internal::WireFormatLite::GetTagFieldNumber(tag)) {
      // optional string transcript = 1;
      case 1: {
        if (tag == 10) {
          DO_(::google::protobuf::internal::WireFormatLite::ReadString(
                input, this->mutable_transcript()));
        } else {
          goto handle_unusual;
        }
        if (input->ExpectTag(21)) goto parse_confidence;
        break;
      }

      // optional float confidence = 2;
      case 2: {
        if (tag == 21) {
         parse_confidence:
          DO_((::google::protobuf::internal::WireFormatLite::ReadPrimitive<
                   float, ::google::protobuf::internal::WireFormatLite::TYPE_FLOAT>(
                 input, &confidence_)));
          set_has_confidence();
        } else {
          goto handle_unusual;
        }
        if (input->ExpectAtEnd()) goto success;
        break;
      }

      default: {
      handle_unusual:
        if (tag == 0 ||
            ::google::protobuf::internal::WireFormatLite::GetTagWireType(tag) ==
            ::google::protobuf::internal::WireFormatLite::WIRETYPE_END_GROUP) {
          goto success;
        }
        DO_(::google::protobuf::internal::WireFormatLite::SkipField(
            input, tag, &unknown_fields_stream));
        break;
      }
    }
  }
success:
  // @@protoc_insertion_point(parse_success:cobalt.speech.proto.SpeechRecognitionAlternative)
  return true;
failure:
  // @@protoc_insertion_point(parse_failure:cobalt.speech.proto.SpeechRecognitionAlternative)
  return false;
#undef DO_
}

void SpeechRecognitionAlternative::SerializeWithCachedSizes(
    ::google::protobuf::io::CodedOutputStream* output) const {
  // @@protoc_insertion_point(serialize_start:cobalt.speech.proto.SpeechRecognitionAlternative)
  // optional string transcript = 1;
  if (has_transcript()) {
    ::google::protobuf::internal::WireFormatLite::WriteStringMaybeAliased(
      1, this->transcript(), output);
  }

  // optional float confidence = 2;
  if (has_confidence()) {
    ::google::protobuf::internal::WireFormatLite::WriteFloat(2, this->confidence(), output);
  }

  output->WriteRaw(unknown_fields().data(),
                   static_cast<int>(unknown_fields().size()));
  // @@protoc_insertion_point(serialize_end:cobalt.speech.proto.SpeechRecognitionAlternative)
}

int SpeechRecognitionAlternative::ByteSize() const {
// @@protoc_insertion_point(message_byte_size_start:cobalt.speech.proto.SpeechRecognitionAlternative)
  int total_size = 0;

  if (_has_bits_[0 / 32] & 3u) {
    // optional string transcript = 1;
    if (has_transcript()) {
      total_size += 1 +
        ::google::protobuf::internal::WireFormatLite::StringSize(
          this->transcript());
    }

    // optional float confidence = 2;
    if (has_confidence()) {
      total_size += 1 + 4;
    }

  }
  total_size += unknown_fields().size();

  GOOGLE_SAFE_CONCURRENT_WRITES_BEGIN();
  _cached_size_ = total_size;
  GOOGLE_SAFE_CONCURRENT_WRITES_END();
  return total_size;
}

void SpeechRecognitionAlternative::CheckTypeAndMergeFrom(
    const ::google::protobuf::MessageLite& from) {
  MergeFrom(*::google::protobuf::down_cast<const SpeechRecognitionAlternative*>(&from));
}

void SpeechRecognitionAlternative::MergeFrom(const SpeechRecognitionAlternative& from) {
// @@protoc_insertion_point(class_specific_merge_from_start:cobalt.speech.proto.SpeechRecognitionAlternative)
  if (GOOGLE_PREDICT_FALSE(&from == this)) MergeFromFail(__LINE__);
  if (from._has_bits_[0 / 32] & (0xffu << (0 % 32))) {
    if (from.has_transcript()) {
      set_has_transcript();
      transcript_.AssignWithDefault(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), from.transcript_);
    }
    if (from.has_confidence()) {
      set_confidence(from.confidence());
    }
  }
  if (!from.unknown_fields().empty()) {
    mutable_unknown_fields()->append(from.unknown_fields());
  }
}

void SpeechRecognitionAlternative::CopyFrom(const SpeechRecognitionAlternative& from) {
// @@protoc_insertion_point(class_specific_copy_from_start:cobalt.speech.proto.SpeechRecognitionAlternative)
  if (&from == this) return;
  Clear();
  MergeFrom(from);
}

bool SpeechRecognitionAlternative::IsInitialized() const {

  return true;
}

void SpeechRecognitionAlternative::Swap(SpeechRecognitionAlternative* other) {
  if (other == this) return;
  InternalSwap(other);
}
void SpeechRecognitionAlternative::InternalSwap(SpeechRecognitionAlternative* other) {
  transcript_.Swap(&other->transcript_);
  std::swap(confidence_, other->confidence_);
  std::swap(_has_bits_[0], other->_has_bits_[0]);
  _unknown_fields_.Swap(&other->_unknown_fields_);
  std::swap(_cached_size_, other->_cached_size_);
}

::std::string SpeechRecognitionAlternative::GetTypeName() const {
  return "cobalt.speech.proto.SpeechRecognitionAlternative";
}

#if PROTOBUF_INLINE_NOT_IN_HEADERS
// SpeechRecognitionAlternative

// optional string transcript = 1;
bool SpeechRecognitionAlternative::has_transcript() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
void SpeechRecognitionAlternative::set_has_transcript() {
  _has_bits_[0] |= 0x00000001u;
}
void SpeechRecognitionAlternative::clear_has_transcript() {
  _has_bits_[0] &= ~0x00000001u;
}
void SpeechRecognitionAlternative::clear_transcript() {
  transcript_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_transcript();
}
 const ::std::string& SpeechRecognitionAlternative::transcript() const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
  return transcript_.GetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
 void SpeechRecognitionAlternative::set_transcript(const ::std::string& value) {
  set_has_transcript();
  transcript_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
}
 void SpeechRecognitionAlternative::set_transcript(const char* value) {
  set_has_transcript();
  transcript_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
}
 void SpeechRecognitionAlternative::set_transcript(const char* value, size_t size) {
  set_has_transcript();
  transcript_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
}
 ::std::string* SpeechRecognitionAlternative::mutable_transcript() {
  set_has_transcript();
  // @@protoc_insertion_point(field_mutable:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
  return transcript_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
 ::std::string* SpeechRecognitionAlternative::release_transcript() {
  // @@protoc_insertion_point(field_release:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
  clear_has_transcript();
  return transcript_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
 void SpeechRecognitionAlternative::set_allocated_transcript(::std::string* transcript) {
  if (transcript != NULL) {
    set_has_transcript();
  } else {
    clear_has_transcript();
  }
  transcript_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), transcript);
  // @@protoc_insertion_point(field_set_allocated:cobalt.speech.proto.SpeechRecognitionAlternative.transcript)
}

// optional float confidence = 2;
bool SpeechRecognitionAlternative::has_confidence() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
void SpeechRecognitionAlternative::set_has_confidence() {
  _has_bits_[0] |= 0x00000002u;
}
void SpeechRecognitionAlternative::clear_has_confidence() {
  _has_bits_[0] &= ~0x00000002u;
}
void SpeechRecognitionAlternative::clear_confidence() {
  confidence_ = 0;
  clear_has_confidence();
}
 float SpeechRecognitionAlternative::confidence() const {
  // @@protoc_insertion_point(field_get:cobalt.speech.proto.SpeechRecognitionAlternative.confidence)
  return confidence_;
}
 void SpeechRecognitionAlternative::set_confidence(float value) {
  set_has_confidence();
  confidence_ = value;
  // @@protoc_insertion_point(field_set:cobalt.speech.proto.SpeechRecognitionAlternative.confidence)
}

#endif  // PROTOBUF_INLINE_NOT_IN_HEADERS

// @@protoc_insertion_point(namespace_scope)

}  // namespace proto
}  // namespace speech
}  // namespace cobalt

// @@protoc_insertion_point(global_scope)
