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

#ifndef PROTOBUF_json_2eproto__INCLUDED
#define PROTOBUF_json_2eproto__INCLUDED

#include <string>

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

#if GOOGLE_PROTOBUF_VERSION < 3003000
#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 3003002 < 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/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/unknown_field_set.h>
// @@protoc_insertion_point(includes)
namespace json_proto {
class ArrayValue;
class ArrayValueDefaultTypeInternal;
extern ArrayValueDefaultTypeInternal _ArrayValue_default_instance_;
class BooleanValue;
class BooleanValueDefaultTypeInternal;
extern BooleanValueDefaultTypeInternal _BooleanValue_default_instance_;
class JsonObject;
class JsonObjectDefaultTypeInternal;
extern JsonObjectDefaultTypeInternal _JsonObject_default_instance_;
class JsonValue;
class JsonValueDefaultTypeInternal;
extern JsonValueDefaultTypeInternal _JsonValue_default_instance_;
class NumberExponent;
class NumberExponentDefaultTypeInternal;
extern NumberExponentDefaultTypeInternal _NumberExponent_default_instance_;
class NumberExponentFrac;
class NumberExponentFracDefaultTypeInternal;
extern NumberExponentFracDefaultTypeInternal _NumberExponentFrac_default_instance_;
class NumberFloat;
class NumberFloatDefaultTypeInternal;
extern NumberFloatDefaultTypeInternal _NumberFloat_default_instance_;
class NumberInteger;
class NumberIntegerDefaultTypeInternal;
extern NumberIntegerDefaultTypeInternal _NumberInteger_default_instance_;
class NumberValue;
class NumberValueDefaultTypeInternal;
extern NumberValueDefaultTypeInternal _NumberValue_default_instance_;
class StringValue;
class StringValueDefaultTypeInternal;
extern StringValueDefaultTypeInternal _StringValue_default_instance_;
}  // namespace json_proto

namespace json_proto {

namespace protobuf_json_2eproto {
// Internal implementation detail -- do not call these.
struct TableStruct {
  static const ::google::protobuf::internal::ParseTableField entries[];
  static const ::google::protobuf::internal::AuxillaryParseTableField aux[];
  static const ::google::protobuf::internal::ParseTable schema[];
  static const ::google::protobuf::uint32 offsets[];
  static void InitDefaultsImpl();
  static void Shutdown();
};
void AddDescriptors();
void InitDefaults();
}  // namespace protobuf_json_2eproto

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

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

  JsonObject(const JsonObject& from);

  inline JsonObject& operator=(const JsonObject& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const JsonObject& default_instance();

  static inline const JsonObject* internal_default_instance() {
    return reinterpret_cast<const JsonObject*>(
               &_JsonObject_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    0;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(JsonObject* other);

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

  inline JsonObject* New() const PROTOBUF_FINAL { return New(NULL); }

  JsonObject* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const JsonObject& from);
  void MergeFrom(const JsonObject& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(JsonObject* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required string name = 1;
  bool has_name() const;
  void clear_name();
  static const int kNameFieldNumber = 1;
  const ::std::string& name() const;
  void set_name(const ::std::string& value);
  #if LANG_CXX11
  void set_name(::std::string&& value);
  #endif
  void set_name(const char* value);
  void set_name(const char* value, size_t size);
  ::std::string* mutable_name();
  ::std::string* release_name();
  void set_allocated_name(::std::string* name);

  // required .json_proto.JsonValue value = 2;
  bool has_value() const;
  void clear_value();
  static const int kValueFieldNumber = 2;
  const ::json_proto::JsonValue& value() const;
  ::json_proto::JsonValue* mutable_value();
  ::json_proto::JsonValue* release_value();
  void set_allocated_value(::json_proto::JsonValue* value);

  // @@protoc_insertion_point(class_scope:json_proto.JsonObject)
 private:
  void set_has_name();
  void clear_has_name();
  void set_has_value();
  void clear_has_value();

  // helper for ByteSizeLong()
  size_t RequiredFieldsByteSizeFallback() const;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr name_;
  ::json_proto::JsonValue* value_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  JsonValue(const JsonValue& from);

  inline JsonValue& operator=(const JsonValue& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const JsonValue& default_instance();

  enum ValueCase {
    kObjectValue = 1,
    kArrayValue = 2,
    kNumberValue = 3,
    kStringValue = 4,
    kBooleanValue = 5,
    VALUE_NOT_SET = 0,
  };

  static inline const JsonValue* internal_default_instance() {
    return reinterpret_cast<const JsonValue*>(
               &_JsonValue_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    1;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(JsonValue* other);

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

  inline JsonValue* New() const PROTOBUF_FINAL { return New(NULL); }

  JsonValue* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const JsonValue& from);
  void MergeFrom(const JsonValue& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(JsonValue* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // optional .json_proto.JsonObject object_value = 1;
  bool has_object_value() const;
  void clear_object_value();
  static const int kObjectValueFieldNumber = 1;
  const ::json_proto::JsonObject& object_value() const;
  ::json_proto::JsonObject* mutable_object_value();
  ::json_proto::JsonObject* release_object_value();
  void set_allocated_object_value(::json_proto::JsonObject* object_value);

  // optional .json_proto.ArrayValue array_value = 2;
  bool has_array_value() const;
  void clear_array_value();
  static const int kArrayValueFieldNumber = 2;
  const ::json_proto::ArrayValue& array_value() const;
  ::json_proto::ArrayValue* mutable_array_value();
  ::json_proto::ArrayValue* release_array_value();
  void set_allocated_array_value(::json_proto::ArrayValue* array_value);

  // optional .json_proto.NumberValue number_value = 3;
  bool has_number_value() const;
  void clear_number_value();
  static const int kNumberValueFieldNumber = 3;
  const ::json_proto::NumberValue& number_value() const;
  ::json_proto::NumberValue* mutable_number_value();
  ::json_proto::NumberValue* release_number_value();
  void set_allocated_number_value(::json_proto::NumberValue* number_value);

  // optional .json_proto.StringValue string_value = 4;
  bool has_string_value() const;
  void clear_string_value();
  static const int kStringValueFieldNumber = 4;
  const ::json_proto::StringValue& string_value() const;
  ::json_proto::StringValue* mutable_string_value();
  ::json_proto::StringValue* release_string_value();
  void set_allocated_string_value(::json_proto::StringValue* string_value);

  // optional .json_proto.BooleanValue boolean_value = 5;
  bool has_boolean_value() const;
  void clear_boolean_value();
  static const int kBooleanValueFieldNumber = 5;
  const ::json_proto::BooleanValue& boolean_value() const;
  ::json_proto::BooleanValue* mutable_boolean_value();
  ::json_proto::BooleanValue* release_boolean_value();
  void set_allocated_boolean_value(::json_proto::BooleanValue* boolean_value);

  ValueCase value_case() const;
  // @@protoc_insertion_point(class_scope:json_proto.JsonValue)
 private:
  void set_has_object_value();
  void set_has_array_value();
  void set_has_number_value();
  void set_has_string_value();
  void set_has_boolean_value();

  inline bool has_value() const;
  void clear_value();
  inline void clear_has_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  union ValueUnion {
    ValueUnion() {}
    ::json_proto::JsonObject* object_value_;
    ::json_proto::ArrayValue* array_value_;
    ::json_proto::NumberValue* number_value_;
    ::json_proto::StringValue* string_value_;
    ::json_proto::BooleanValue* boolean_value_;
  } value_;
  ::google::protobuf::uint32 _oneof_case_[1];

  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  ArrayValue(const ArrayValue& from);

  inline ArrayValue& operator=(const ArrayValue& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const ArrayValue& default_instance();

  static inline const ArrayValue* internal_default_instance() {
    return reinterpret_cast<const ArrayValue*>(
               &_ArrayValue_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    2;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(ArrayValue* other);

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

  inline ArrayValue* New() const PROTOBUF_FINAL { return New(NULL); }

  ArrayValue* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const ArrayValue& from);
  void MergeFrom(const ArrayValue& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(ArrayValue* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // repeated .json_proto.JsonValue value = 1;
  int value_size() const;
  void clear_value();
  static const int kValueFieldNumber = 1;
  const ::json_proto::JsonValue& value(int index) const;
  ::json_proto::JsonValue* mutable_value(int index);
  ::json_proto::JsonValue* add_value();
  ::google::protobuf::RepeatedPtrField< ::json_proto::JsonValue >*
      mutable_value();
  const ::google::protobuf::RepeatedPtrField< ::json_proto::JsonValue >&
      value() const;

  // @@protoc_insertion_point(class_scope:json_proto.ArrayValue)
 private:

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::RepeatedPtrField< ::json_proto::JsonValue > value_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  NumberInteger(const NumberInteger& from);

  inline NumberInteger& operator=(const NumberInteger& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NumberInteger& default_instance();

  static inline const NumberInteger* internal_default_instance() {
    return reinterpret_cast<const NumberInteger*>(
               &_NumberInteger_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    3;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(NumberInteger* other);

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

  inline NumberInteger* New() const PROTOBUF_FINAL { return New(NULL); }

  NumberInteger* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const NumberInteger& from);
  void MergeFrom(const NumberInteger& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(NumberInteger* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required int64 value = 1;
  bool has_value() const;
  void clear_value();
  static const int kValueFieldNumber = 1;
  ::google::protobuf::int64 value() const;
  void set_value(::google::protobuf::int64 value);

  // @@protoc_insertion_point(class_scope:json_proto.NumberInteger)
 private:
  void set_has_value();
  void clear_has_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::int64 value_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  NumberFloat(const NumberFloat& from);

  inline NumberFloat& operator=(const NumberFloat& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NumberFloat& default_instance();

  static inline const NumberFloat* internal_default_instance() {
    return reinterpret_cast<const NumberFloat*>(
               &_NumberFloat_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    4;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(NumberFloat* other);

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

  inline NumberFloat* New() const PROTOBUF_FINAL { return New(NULL); }

  NumberFloat* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const NumberFloat& from);
  void MergeFrom(const NumberFloat& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(NumberFloat* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required double value = 1;
  bool has_value() const;
  void clear_value();
  static const int kValueFieldNumber = 1;
  double value() const;
  void set_value(double value);

  // @@protoc_insertion_point(class_scope:json_proto.NumberFloat)
 private:
  void set_has_value();
  void clear_has_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  double value_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  NumberExponent(const NumberExponent& from);

  inline NumberExponent& operator=(const NumberExponent& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NumberExponent& default_instance();

  static inline const NumberExponent* internal_default_instance() {
    return reinterpret_cast<const NumberExponent*>(
               &_NumberExponent_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    5;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(NumberExponent* other);

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

  inline NumberExponent* New() const PROTOBUF_FINAL { return New(NULL); }

  NumberExponent* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const NumberExponent& from);
  void MergeFrom(const NumberExponent& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(NumberExponent* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required int32 base = 1;
  bool has_base() const;
  void clear_base();
  static const int kBaseFieldNumber = 1;
  ::google::protobuf::int32 base() const;
  void set_base(::google::protobuf::int32 value);

  // required int32 exponent = 2;
  bool has_exponent() const;
  void clear_exponent();
  static const int kExponentFieldNumber = 2;
  ::google::protobuf::int32 exponent() const;
  void set_exponent(::google::protobuf::int32 value);

  // required bool use_uppercase = 3;
  bool has_use_uppercase() const;
  void clear_use_uppercase();
  static const int kUseUppercaseFieldNumber = 3;
  bool use_uppercase() const;
  void set_use_uppercase(bool value);

  // @@protoc_insertion_point(class_scope:json_proto.NumberExponent)
 private:
  void set_has_base();
  void clear_has_base();
  void set_has_exponent();
  void clear_has_exponent();
  void set_has_use_uppercase();
  void clear_has_use_uppercase();

  // helper for ByteSizeLong()
  size_t RequiredFieldsByteSizeFallback() const;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::int32 base_;
  ::google::protobuf::int32 exponent_;
  bool use_uppercase_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  NumberExponentFrac(const NumberExponentFrac& from);

  inline NumberExponentFrac& operator=(const NumberExponentFrac& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NumberExponentFrac& default_instance();

  static inline const NumberExponentFrac* internal_default_instance() {
    return reinterpret_cast<const NumberExponentFrac*>(
               &_NumberExponentFrac_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    6;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(NumberExponentFrac* other);

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

  inline NumberExponentFrac* New() const PROTOBUF_FINAL { return New(NULL); }

  NumberExponentFrac* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const NumberExponentFrac& from);
  void MergeFrom(const NumberExponentFrac& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(NumberExponentFrac* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required float base = 1;
  bool has_base() const;
  void clear_base();
  static const int kBaseFieldNumber = 1;
  float base() const;
  void set_base(float value);

  // required int32 exponent = 2;
  bool has_exponent() const;
  void clear_exponent();
  static const int kExponentFieldNumber = 2;
  ::google::protobuf::int32 exponent() const;
  void set_exponent(::google::protobuf::int32 value);

  // required bool use_uppercase = 3;
  bool has_use_uppercase() const;
  void clear_use_uppercase();
  static const int kUseUppercaseFieldNumber = 3;
  bool use_uppercase() const;
  void set_use_uppercase(bool value);

  // @@protoc_insertion_point(class_scope:json_proto.NumberExponentFrac)
 private:
  void set_has_base();
  void clear_has_base();
  void set_has_exponent();
  void clear_has_exponent();
  void set_has_use_uppercase();
  void clear_has_use_uppercase();

  // helper for ByteSizeLong()
  size_t RequiredFieldsByteSizeFallback() const;

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  float base_;
  ::google::protobuf::int32 exponent_;
  bool use_uppercase_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  NumberValue(const NumberValue& from);

  inline NumberValue& operator=(const NumberValue& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const NumberValue& default_instance();

  enum ValueCase {
    kFloatValue = 2,
    kExponentValue = 3,
    kExponentFracValue = 4,
    VALUE_NOT_SET = 0,
  };

  static inline const NumberValue* internal_default_instance() {
    return reinterpret_cast<const NumberValue*>(
               &_NumberValue_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    7;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(NumberValue* other);

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

  inline NumberValue* New() const PROTOBUF_FINAL { return New(NULL); }

  NumberValue* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const NumberValue& from);
  void MergeFrom(const NumberValue& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(NumberValue* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required .json_proto.NumberInteger integer_value = 1;
  bool has_integer_value() const;
  void clear_integer_value();
  static const int kIntegerValueFieldNumber = 1;
  const ::json_proto::NumberInteger& integer_value() const;
  ::json_proto::NumberInteger* mutable_integer_value();
  ::json_proto::NumberInteger* release_integer_value();
  void set_allocated_integer_value(::json_proto::NumberInteger* integer_value);

  // optional .json_proto.NumberFloat float_value = 2;
  bool has_float_value() const;
  void clear_float_value();
  static const int kFloatValueFieldNumber = 2;
  const ::json_proto::NumberFloat& float_value() const;
  ::json_proto::NumberFloat* mutable_float_value();
  ::json_proto::NumberFloat* release_float_value();
  void set_allocated_float_value(::json_proto::NumberFloat* float_value);

  // optional .json_proto.NumberExponent exponent_value = 3;
  bool has_exponent_value() const;
  void clear_exponent_value();
  static const int kExponentValueFieldNumber = 3;
  const ::json_proto::NumberExponent& exponent_value() const;
  ::json_proto::NumberExponent* mutable_exponent_value();
  ::json_proto::NumberExponent* release_exponent_value();
  void set_allocated_exponent_value(::json_proto::NumberExponent* exponent_value);

  // optional .json_proto.NumberExponentFrac exponent_frac_value = 4;
  bool has_exponent_frac_value() const;
  void clear_exponent_frac_value();
  static const int kExponentFracValueFieldNumber = 4;
  const ::json_proto::NumberExponentFrac& exponent_frac_value() const;
  ::json_proto::NumberExponentFrac* mutable_exponent_frac_value();
  ::json_proto::NumberExponentFrac* release_exponent_frac_value();
  void set_allocated_exponent_frac_value(::json_proto::NumberExponentFrac* exponent_frac_value);

  ValueCase value_case() const;
  // @@protoc_insertion_point(class_scope:json_proto.NumberValue)
 private:
  void set_has_integer_value();
  void clear_has_integer_value();
  void set_has_float_value();
  void set_has_exponent_value();
  void set_has_exponent_frac_value();

  inline bool has_value() const;
  void clear_value();
  inline void clear_has_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::json_proto::NumberInteger* integer_value_;
  union ValueUnion {
    ValueUnion() {}
    ::json_proto::NumberFloat* float_value_;
    ::json_proto::NumberExponent* exponent_value_;
    ::json_proto::NumberExponentFrac* exponent_frac_value_;
  } value_;
  ::google::protobuf::uint32 _oneof_case_[1];

  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  StringValue(const StringValue& from);

  inline StringValue& operator=(const StringValue& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const StringValue& default_instance();

  static inline const StringValue* internal_default_instance() {
    return reinterpret_cast<const StringValue*>(
               &_StringValue_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    8;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(StringValue* other);

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

  inline StringValue* New() const PROTOBUF_FINAL { return New(NULL); }

  StringValue* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const StringValue& from);
  void MergeFrom(const StringValue& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(StringValue* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required string value = 1;
  bool has_value() const;
  void clear_value();
  static const int kValueFieldNumber = 1;
  const ::std::string& value() const;
  void set_value(const ::std::string& value);
  #if LANG_CXX11
  void set_value(::std::string&& value);
  #endif
  void set_value(const char* value);
  void set_value(const char* value, size_t size);
  ::std::string* mutable_value();
  ::std::string* release_value();
  void set_allocated_value(::std::string* value);

  // @@protoc_insertion_point(class_scope:json_proto.StringValue)
 private:
  void set_has_value();
  void clear_has_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  ::google::protobuf::internal::ArenaStringPtr value_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// -------------------------------------------------------------------

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

  BooleanValue(const BooleanValue& from);

  inline BooleanValue& operator=(const BooleanValue& from) {
    CopyFrom(from);
    return *this;
  }

  inline const ::google::protobuf::UnknownFieldSet& unknown_fields() const {
    return _internal_metadata_.unknown_fields();
  }

  inline ::google::protobuf::UnknownFieldSet* mutable_unknown_fields() {
    return _internal_metadata_.mutable_unknown_fields();
  }

  static const ::google::protobuf::Descriptor* descriptor();
  static const BooleanValue& default_instance();

  static inline const BooleanValue* internal_default_instance() {
    return reinterpret_cast<const BooleanValue*>(
               &_BooleanValue_default_instance_);
  }
  static PROTOBUF_CONSTEXPR int const kIndexInFileMessages =
    9;

  GOOGLE_ATTRIBUTE_NOINLINE void Swap(BooleanValue* other);

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

  inline BooleanValue* New() const PROTOBUF_FINAL { return New(NULL); }

  BooleanValue* New(::google::protobuf::Arena* arena) const PROTOBUF_FINAL;
  void CopyFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void MergeFrom(const ::google::protobuf::Message& from) PROTOBUF_FINAL;
  void CopyFrom(const BooleanValue& from);
  void MergeFrom(const BooleanValue& from);
  void Clear() PROTOBUF_FINAL;
  bool IsInitialized() const PROTOBUF_FINAL;

  size_t ByteSizeLong() const PROTOBUF_FINAL;
  bool MergePartialFromCodedStream(
      ::google::protobuf::io::CodedInputStream* input) PROTOBUF_FINAL;
  void SerializeWithCachedSizes(
      ::google::protobuf::io::CodedOutputStream* output) const PROTOBUF_FINAL;
  ::google::protobuf::uint8* InternalSerializeWithCachedSizesToArray(
      bool deterministic, ::google::protobuf::uint8* target) const PROTOBUF_FINAL;
  int GetCachedSize() const PROTOBUF_FINAL { return _cached_size_; }
  private:
  void SharedCtor();
  void SharedDtor();
  void SetCachedSize(int size) const PROTOBUF_FINAL;
  void InternalSwap(BooleanValue* other);
  private:
  inline ::google::protobuf::Arena* GetArenaNoVirtual() const {
    return NULL;
  }
  inline void* MaybeArenaPtr() const {
    return NULL;
  }
  public:

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

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

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

  // required bool value = 1;
  bool has_value() const;
  void clear_value();
  static const int kValueFieldNumber = 1;
  bool value() const;
  void set_value(bool value);

  // @@protoc_insertion_point(class_scope:json_proto.BooleanValue)
 private:
  void set_has_value();
  void clear_has_value();

  ::google::protobuf::internal::InternalMetadataWithArena _internal_metadata_;
  ::google::protobuf::internal::HasBits<1> _has_bits_;
  mutable int _cached_size_;
  bool value_;
  friend struct protobuf_json_2eproto::TableStruct;
};
// ===================================================================


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

#if !PROTOBUF_INLINE_NOT_IN_HEADERS
// JsonObject

// required string name = 1;
inline bool JsonObject::has_name() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void JsonObject::set_has_name() {
  _has_bits_[0] |= 0x00000001u;
}
inline void JsonObject::clear_has_name() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void JsonObject::clear_name() {
  name_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_name();
}
inline const ::std::string& JsonObject::name() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonObject.name)
  return name_.GetNoArena();
}
inline void JsonObject::set_name(const ::std::string& value) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:json_proto.JsonObject.name)
}
#if LANG_CXX11
inline void JsonObject::set_name(::std::string&& value) {
  set_has_name();
  name_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:json_proto.JsonObject.name)
}
#endif
inline void JsonObject::set_name(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:json_proto.JsonObject.name)
}
inline void JsonObject::set_name(const char* value, size_t size) {
  set_has_name();
  name_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:json_proto.JsonObject.name)
}
inline ::std::string* JsonObject::mutable_name() {
  set_has_name();
  // @@protoc_insertion_point(field_mutable:json_proto.JsonObject.name)
  return name_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* JsonObject::release_name() {
  // @@protoc_insertion_point(field_release:json_proto.JsonObject.name)
  clear_has_name();
  return name_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void JsonObject::set_allocated_name(::std::string* name) {
  if (name != NULL) {
    set_has_name();
  } else {
    clear_has_name();
  }
  name_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), name);
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonObject.name)
}

// required .json_proto.JsonValue value = 2;
inline bool JsonObject::has_value() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void JsonObject::set_has_value() {
  _has_bits_[0] |= 0x00000002u;
}
inline void JsonObject::clear_has_value() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void JsonObject::clear_value() {
  if (value_ != NULL) value_->::json_proto::JsonValue::Clear();
  clear_has_value();
}
inline const ::json_proto::JsonValue& JsonObject::value() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonObject.value)
  return value_ != NULL ? *value_
                         : *::json_proto::JsonValue::internal_default_instance();
}
inline ::json_proto::JsonValue* JsonObject::mutable_value() {
  set_has_value();
  if (value_ == NULL) {
    value_ = new ::json_proto::JsonValue;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.JsonObject.value)
  return value_;
}
inline ::json_proto::JsonValue* JsonObject::release_value() {
  // @@protoc_insertion_point(field_release:json_proto.JsonObject.value)
  clear_has_value();
  ::json_proto::JsonValue* temp = value_;
  value_ = NULL;
  return temp;
}
inline void JsonObject::set_allocated_value(::json_proto::JsonValue* value) {
  delete value_;
  value_ = value;
  if (value) {
    set_has_value();
  } else {
    clear_has_value();
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonObject.value)
}

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

// JsonValue

// optional .json_proto.JsonObject object_value = 1;
inline bool JsonValue::has_object_value() const {
  return value_case() == kObjectValue;
}
inline void JsonValue::set_has_object_value() {
  _oneof_case_[0] = kObjectValue;
}
inline void JsonValue::clear_object_value() {
  if (has_object_value()) {
    delete value_.object_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::JsonObject& JsonValue::object_value() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonValue.object_value)
  return has_object_value()
      ? *value_.object_value_
      : ::json_proto::JsonObject::default_instance();
}
inline ::json_proto::JsonObject* JsonValue::mutable_object_value() {
  if (!has_object_value()) {
    clear_value();
    set_has_object_value();
    value_.object_value_ = new ::json_proto::JsonObject;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.JsonValue.object_value)
  return value_.object_value_;
}
inline ::json_proto::JsonObject* JsonValue::release_object_value() {
  // @@protoc_insertion_point(field_release:json_proto.JsonValue.object_value)
  if (has_object_value()) {
    clear_has_value();
    ::json_proto::JsonObject* temp = value_.object_value_;
    value_.object_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void JsonValue::set_allocated_object_value(::json_proto::JsonObject* object_value) {
  clear_value();
  if (object_value) {
    set_has_object_value();
    value_.object_value_ = object_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonValue.object_value)
}

// optional .json_proto.ArrayValue array_value = 2;
inline bool JsonValue::has_array_value() const {
  return value_case() == kArrayValue;
}
inline void JsonValue::set_has_array_value() {
  _oneof_case_[0] = kArrayValue;
}
inline void JsonValue::clear_array_value() {
  if (has_array_value()) {
    delete value_.array_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::ArrayValue& JsonValue::array_value() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonValue.array_value)
  return has_array_value()
      ? *value_.array_value_
      : ::json_proto::ArrayValue::default_instance();
}
inline ::json_proto::ArrayValue* JsonValue::mutable_array_value() {
  if (!has_array_value()) {
    clear_value();
    set_has_array_value();
    value_.array_value_ = new ::json_proto::ArrayValue;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.JsonValue.array_value)
  return value_.array_value_;
}
inline ::json_proto::ArrayValue* JsonValue::release_array_value() {
  // @@protoc_insertion_point(field_release:json_proto.JsonValue.array_value)
  if (has_array_value()) {
    clear_has_value();
    ::json_proto::ArrayValue* temp = value_.array_value_;
    value_.array_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void JsonValue::set_allocated_array_value(::json_proto::ArrayValue* array_value) {
  clear_value();
  if (array_value) {
    set_has_array_value();
    value_.array_value_ = array_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonValue.array_value)
}

// optional .json_proto.NumberValue number_value = 3;
inline bool JsonValue::has_number_value() const {
  return value_case() == kNumberValue;
}
inline void JsonValue::set_has_number_value() {
  _oneof_case_[0] = kNumberValue;
}
inline void JsonValue::clear_number_value() {
  if (has_number_value()) {
    delete value_.number_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::NumberValue& JsonValue::number_value() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonValue.number_value)
  return has_number_value()
      ? *value_.number_value_
      : ::json_proto::NumberValue::default_instance();
}
inline ::json_proto::NumberValue* JsonValue::mutable_number_value() {
  if (!has_number_value()) {
    clear_value();
    set_has_number_value();
    value_.number_value_ = new ::json_proto::NumberValue;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.JsonValue.number_value)
  return value_.number_value_;
}
inline ::json_proto::NumberValue* JsonValue::release_number_value() {
  // @@protoc_insertion_point(field_release:json_proto.JsonValue.number_value)
  if (has_number_value()) {
    clear_has_value();
    ::json_proto::NumberValue* temp = value_.number_value_;
    value_.number_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void JsonValue::set_allocated_number_value(::json_proto::NumberValue* number_value) {
  clear_value();
  if (number_value) {
    set_has_number_value();
    value_.number_value_ = number_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonValue.number_value)
}

// optional .json_proto.StringValue string_value = 4;
inline bool JsonValue::has_string_value() const {
  return value_case() == kStringValue;
}
inline void JsonValue::set_has_string_value() {
  _oneof_case_[0] = kStringValue;
}
inline void JsonValue::clear_string_value() {
  if (has_string_value()) {
    delete value_.string_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::StringValue& JsonValue::string_value() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonValue.string_value)
  return has_string_value()
      ? *value_.string_value_
      : ::json_proto::StringValue::default_instance();
}
inline ::json_proto::StringValue* JsonValue::mutable_string_value() {
  if (!has_string_value()) {
    clear_value();
    set_has_string_value();
    value_.string_value_ = new ::json_proto::StringValue;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.JsonValue.string_value)
  return value_.string_value_;
}
inline ::json_proto::StringValue* JsonValue::release_string_value() {
  // @@protoc_insertion_point(field_release:json_proto.JsonValue.string_value)
  if (has_string_value()) {
    clear_has_value();
    ::json_proto::StringValue* temp = value_.string_value_;
    value_.string_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void JsonValue::set_allocated_string_value(::json_proto::StringValue* string_value) {
  clear_value();
  if (string_value) {
    set_has_string_value();
    value_.string_value_ = string_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonValue.string_value)
}

// optional .json_proto.BooleanValue boolean_value = 5;
inline bool JsonValue::has_boolean_value() const {
  return value_case() == kBooleanValue;
}
inline void JsonValue::set_has_boolean_value() {
  _oneof_case_[0] = kBooleanValue;
}
inline void JsonValue::clear_boolean_value() {
  if (has_boolean_value()) {
    delete value_.boolean_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::BooleanValue& JsonValue::boolean_value() const {
  // @@protoc_insertion_point(field_get:json_proto.JsonValue.boolean_value)
  return has_boolean_value()
      ? *value_.boolean_value_
      : ::json_proto::BooleanValue::default_instance();
}
inline ::json_proto::BooleanValue* JsonValue::mutable_boolean_value() {
  if (!has_boolean_value()) {
    clear_value();
    set_has_boolean_value();
    value_.boolean_value_ = new ::json_proto::BooleanValue;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.JsonValue.boolean_value)
  return value_.boolean_value_;
}
inline ::json_proto::BooleanValue* JsonValue::release_boolean_value() {
  // @@protoc_insertion_point(field_release:json_proto.JsonValue.boolean_value)
  if (has_boolean_value()) {
    clear_has_value();
    ::json_proto::BooleanValue* temp = value_.boolean_value_;
    value_.boolean_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void JsonValue::set_allocated_boolean_value(::json_proto::BooleanValue* boolean_value) {
  clear_value();
  if (boolean_value) {
    set_has_boolean_value();
    value_.boolean_value_ = boolean_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.JsonValue.boolean_value)
}

inline bool JsonValue::has_value() const {
  return value_case() != VALUE_NOT_SET;
}
inline void JsonValue::clear_has_value() {
  _oneof_case_[0] = VALUE_NOT_SET;
}
inline JsonValue::ValueCase JsonValue::value_case() const {
  return JsonValue::ValueCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// ArrayValue

// repeated .json_proto.JsonValue value = 1;
inline int ArrayValue::value_size() const {
  return value_.size();
}
inline void ArrayValue::clear_value() {
  value_.Clear();
}
inline const ::json_proto::JsonValue& ArrayValue::value(int index) const {
  // @@protoc_insertion_point(field_get:json_proto.ArrayValue.value)
  return value_.Get(index);
}
inline ::json_proto::JsonValue* ArrayValue::mutable_value(int index) {
  // @@protoc_insertion_point(field_mutable:json_proto.ArrayValue.value)
  return value_.Mutable(index);
}
inline ::json_proto::JsonValue* ArrayValue::add_value() {
  // @@protoc_insertion_point(field_add:json_proto.ArrayValue.value)
  return value_.Add();
}
inline ::google::protobuf::RepeatedPtrField< ::json_proto::JsonValue >*
ArrayValue::mutable_value() {
  // @@protoc_insertion_point(field_mutable_list:json_proto.ArrayValue.value)
  return &value_;
}
inline const ::google::protobuf::RepeatedPtrField< ::json_proto::JsonValue >&
ArrayValue::value() const {
  // @@protoc_insertion_point(field_list:json_proto.ArrayValue.value)
  return value_;
}

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

// NumberInteger

// required int64 value = 1;
inline bool NumberInteger::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NumberInteger::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NumberInteger::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NumberInteger::clear_value() {
  value_ = GOOGLE_LONGLONG(0);
  clear_has_value();
}
inline ::google::protobuf::int64 NumberInteger::value() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberInteger.value)
  return value_;
}
inline void NumberInteger::set_value(::google::protobuf::int64 value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberInteger.value)
}

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

// NumberFloat

// required double value = 1;
inline bool NumberFloat::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NumberFloat::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NumberFloat::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NumberFloat::clear_value() {
  value_ = 0;
  clear_has_value();
}
inline double NumberFloat::value() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberFloat.value)
  return value_;
}
inline void NumberFloat::set_value(double value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberFloat.value)
}

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

// NumberExponent

// required int32 base = 1;
inline bool NumberExponent::has_base() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NumberExponent::set_has_base() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NumberExponent::clear_has_base() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NumberExponent::clear_base() {
  base_ = 0;
  clear_has_base();
}
inline ::google::protobuf::int32 NumberExponent::base() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberExponent.base)
  return base_;
}
inline void NumberExponent::set_base(::google::protobuf::int32 value) {
  set_has_base();
  base_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberExponent.base)
}

// required int32 exponent = 2;
inline bool NumberExponent::has_exponent() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void NumberExponent::set_has_exponent() {
  _has_bits_[0] |= 0x00000002u;
}
inline void NumberExponent::clear_has_exponent() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void NumberExponent::clear_exponent() {
  exponent_ = 0;
  clear_has_exponent();
}
inline ::google::protobuf::int32 NumberExponent::exponent() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberExponent.exponent)
  return exponent_;
}
inline void NumberExponent::set_exponent(::google::protobuf::int32 value) {
  set_has_exponent();
  exponent_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberExponent.exponent)
}

// required bool use_uppercase = 3;
inline bool NumberExponent::has_use_uppercase() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void NumberExponent::set_has_use_uppercase() {
  _has_bits_[0] |= 0x00000004u;
}
inline void NumberExponent::clear_has_use_uppercase() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void NumberExponent::clear_use_uppercase() {
  use_uppercase_ = false;
  clear_has_use_uppercase();
}
inline bool NumberExponent::use_uppercase() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberExponent.use_uppercase)
  return use_uppercase_;
}
inline void NumberExponent::set_use_uppercase(bool value) {
  set_has_use_uppercase();
  use_uppercase_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberExponent.use_uppercase)
}

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

// NumberExponentFrac

// required float base = 1;
inline bool NumberExponentFrac::has_base() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NumberExponentFrac::set_has_base() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NumberExponentFrac::clear_has_base() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NumberExponentFrac::clear_base() {
  base_ = 0;
  clear_has_base();
}
inline float NumberExponentFrac::base() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberExponentFrac.base)
  return base_;
}
inline void NumberExponentFrac::set_base(float value) {
  set_has_base();
  base_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberExponentFrac.base)
}

// required int32 exponent = 2;
inline bool NumberExponentFrac::has_exponent() const {
  return (_has_bits_[0] & 0x00000002u) != 0;
}
inline void NumberExponentFrac::set_has_exponent() {
  _has_bits_[0] |= 0x00000002u;
}
inline void NumberExponentFrac::clear_has_exponent() {
  _has_bits_[0] &= ~0x00000002u;
}
inline void NumberExponentFrac::clear_exponent() {
  exponent_ = 0;
  clear_has_exponent();
}
inline ::google::protobuf::int32 NumberExponentFrac::exponent() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberExponentFrac.exponent)
  return exponent_;
}
inline void NumberExponentFrac::set_exponent(::google::protobuf::int32 value) {
  set_has_exponent();
  exponent_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberExponentFrac.exponent)
}

// required bool use_uppercase = 3;
inline bool NumberExponentFrac::has_use_uppercase() const {
  return (_has_bits_[0] & 0x00000004u) != 0;
}
inline void NumberExponentFrac::set_has_use_uppercase() {
  _has_bits_[0] |= 0x00000004u;
}
inline void NumberExponentFrac::clear_has_use_uppercase() {
  _has_bits_[0] &= ~0x00000004u;
}
inline void NumberExponentFrac::clear_use_uppercase() {
  use_uppercase_ = false;
  clear_has_use_uppercase();
}
inline bool NumberExponentFrac::use_uppercase() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberExponentFrac.use_uppercase)
  return use_uppercase_;
}
inline void NumberExponentFrac::set_use_uppercase(bool value) {
  set_has_use_uppercase();
  use_uppercase_ = value;
  // @@protoc_insertion_point(field_set:json_proto.NumberExponentFrac.use_uppercase)
}

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

// NumberValue

// required .json_proto.NumberInteger integer_value = 1;
inline bool NumberValue::has_integer_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void NumberValue::set_has_integer_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void NumberValue::clear_has_integer_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void NumberValue::clear_integer_value() {
  if (integer_value_ != NULL) integer_value_->::json_proto::NumberInteger::Clear();
  clear_has_integer_value();
}
inline const ::json_proto::NumberInteger& NumberValue::integer_value() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberValue.integer_value)
  return integer_value_ != NULL ? *integer_value_
                         : *::json_proto::NumberInteger::internal_default_instance();
}
inline ::json_proto::NumberInteger* NumberValue::mutable_integer_value() {
  set_has_integer_value();
  if (integer_value_ == NULL) {
    integer_value_ = new ::json_proto::NumberInteger;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.NumberValue.integer_value)
  return integer_value_;
}
inline ::json_proto::NumberInteger* NumberValue::release_integer_value() {
  // @@protoc_insertion_point(field_release:json_proto.NumberValue.integer_value)
  clear_has_integer_value();
  ::json_proto::NumberInteger* temp = integer_value_;
  integer_value_ = NULL;
  return temp;
}
inline void NumberValue::set_allocated_integer_value(::json_proto::NumberInteger* integer_value) {
  delete integer_value_;
  integer_value_ = integer_value;
  if (integer_value) {
    set_has_integer_value();
  } else {
    clear_has_integer_value();
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.NumberValue.integer_value)
}

// optional .json_proto.NumberFloat float_value = 2;
inline bool NumberValue::has_float_value() const {
  return value_case() == kFloatValue;
}
inline void NumberValue::set_has_float_value() {
  _oneof_case_[0] = kFloatValue;
}
inline void NumberValue::clear_float_value() {
  if (has_float_value()) {
    delete value_.float_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::NumberFloat& NumberValue::float_value() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberValue.float_value)
  return has_float_value()
      ? *value_.float_value_
      : ::json_proto::NumberFloat::default_instance();
}
inline ::json_proto::NumberFloat* NumberValue::mutable_float_value() {
  if (!has_float_value()) {
    clear_value();
    set_has_float_value();
    value_.float_value_ = new ::json_proto::NumberFloat;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.NumberValue.float_value)
  return value_.float_value_;
}
inline ::json_proto::NumberFloat* NumberValue::release_float_value() {
  // @@protoc_insertion_point(field_release:json_proto.NumberValue.float_value)
  if (has_float_value()) {
    clear_has_value();
    ::json_proto::NumberFloat* temp = value_.float_value_;
    value_.float_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void NumberValue::set_allocated_float_value(::json_proto::NumberFloat* float_value) {
  clear_value();
  if (float_value) {
    set_has_float_value();
    value_.float_value_ = float_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.NumberValue.float_value)
}

// optional .json_proto.NumberExponent exponent_value = 3;
inline bool NumberValue::has_exponent_value() const {
  return value_case() == kExponentValue;
}
inline void NumberValue::set_has_exponent_value() {
  _oneof_case_[0] = kExponentValue;
}
inline void NumberValue::clear_exponent_value() {
  if (has_exponent_value()) {
    delete value_.exponent_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::NumberExponent& NumberValue::exponent_value() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberValue.exponent_value)
  return has_exponent_value()
      ? *value_.exponent_value_
      : ::json_proto::NumberExponent::default_instance();
}
inline ::json_proto::NumberExponent* NumberValue::mutable_exponent_value() {
  if (!has_exponent_value()) {
    clear_value();
    set_has_exponent_value();
    value_.exponent_value_ = new ::json_proto::NumberExponent;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.NumberValue.exponent_value)
  return value_.exponent_value_;
}
inline ::json_proto::NumberExponent* NumberValue::release_exponent_value() {
  // @@protoc_insertion_point(field_release:json_proto.NumberValue.exponent_value)
  if (has_exponent_value()) {
    clear_has_value();
    ::json_proto::NumberExponent* temp = value_.exponent_value_;
    value_.exponent_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void NumberValue::set_allocated_exponent_value(::json_proto::NumberExponent* exponent_value) {
  clear_value();
  if (exponent_value) {
    set_has_exponent_value();
    value_.exponent_value_ = exponent_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.NumberValue.exponent_value)
}

// optional .json_proto.NumberExponentFrac exponent_frac_value = 4;
inline bool NumberValue::has_exponent_frac_value() const {
  return value_case() == kExponentFracValue;
}
inline void NumberValue::set_has_exponent_frac_value() {
  _oneof_case_[0] = kExponentFracValue;
}
inline void NumberValue::clear_exponent_frac_value() {
  if (has_exponent_frac_value()) {
    delete value_.exponent_frac_value_;
    clear_has_value();
  }
}
inline  const ::json_proto::NumberExponentFrac& NumberValue::exponent_frac_value() const {
  // @@protoc_insertion_point(field_get:json_proto.NumberValue.exponent_frac_value)
  return has_exponent_frac_value()
      ? *value_.exponent_frac_value_
      : ::json_proto::NumberExponentFrac::default_instance();
}
inline ::json_proto::NumberExponentFrac* NumberValue::mutable_exponent_frac_value() {
  if (!has_exponent_frac_value()) {
    clear_value();
    set_has_exponent_frac_value();
    value_.exponent_frac_value_ = new ::json_proto::NumberExponentFrac;
  }
  // @@protoc_insertion_point(field_mutable:json_proto.NumberValue.exponent_frac_value)
  return value_.exponent_frac_value_;
}
inline ::json_proto::NumberExponentFrac* NumberValue::release_exponent_frac_value() {
  // @@protoc_insertion_point(field_release:json_proto.NumberValue.exponent_frac_value)
  if (has_exponent_frac_value()) {
    clear_has_value();
    ::json_proto::NumberExponentFrac* temp = value_.exponent_frac_value_;
    value_.exponent_frac_value_ = NULL;
    return temp;
  } else {
    return NULL;
  }
}
inline void NumberValue::set_allocated_exponent_frac_value(::json_proto::NumberExponentFrac* exponent_frac_value) {
  clear_value();
  if (exponent_frac_value) {
    set_has_exponent_frac_value();
    value_.exponent_frac_value_ = exponent_frac_value;
  }
  // @@protoc_insertion_point(field_set_allocated:json_proto.NumberValue.exponent_frac_value)
}

inline bool NumberValue::has_value() const {
  return value_case() != VALUE_NOT_SET;
}
inline void NumberValue::clear_has_value() {
  _oneof_case_[0] = VALUE_NOT_SET;
}
inline NumberValue::ValueCase NumberValue::value_case() const {
  return NumberValue::ValueCase(_oneof_case_[0]);
}
// -------------------------------------------------------------------

// StringValue

// required string value = 1;
inline bool StringValue::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void StringValue::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void StringValue::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void StringValue::clear_value() {
  value_.ClearToEmptyNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
  clear_has_value();
}
inline const ::std::string& StringValue::value() const {
  // @@protoc_insertion_point(field_get:json_proto.StringValue.value)
  return value_.GetNoArena();
}
inline void StringValue::set_value(const ::std::string& value) {
  set_has_value();
  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set:json_proto.StringValue.value)
}
#if LANG_CXX11
inline void StringValue::set_value(::std::string&& value) {
  set_has_value();
  value_.SetNoArena(
    &::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::move(value));
  // @@protoc_insertion_point(field_set_rvalue:json_proto.StringValue.value)
}
#endif
inline void StringValue::set_value(const char* value) {
  GOOGLE_DCHECK(value != NULL);
  set_has_value();
  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), ::std::string(value));
  // @@protoc_insertion_point(field_set_char:json_proto.StringValue.value)
}
inline void StringValue::set_value(const char* value, size_t size) {
  set_has_value();
  value_.SetNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(),
      ::std::string(reinterpret_cast<const char*>(value), size));
  // @@protoc_insertion_point(field_set_pointer:json_proto.StringValue.value)
}
inline ::std::string* StringValue::mutable_value() {
  set_has_value();
  // @@protoc_insertion_point(field_mutable:json_proto.StringValue.value)
  return value_.MutableNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline ::std::string* StringValue::release_value() {
  // @@protoc_insertion_point(field_release:json_proto.StringValue.value)
  clear_has_value();
  return value_.ReleaseNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited());
}
inline void StringValue::set_allocated_value(::std::string* value) {
  if (value != NULL) {
    set_has_value();
  } else {
    clear_has_value();
  }
  value_.SetAllocatedNoArena(&::google::protobuf::internal::GetEmptyStringAlreadyInited(), value);
  // @@protoc_insertion_point(field_set_allocated:json_proto.StringValue.value)
}

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

// BooleanValue

// required bool value = 1;
inline bool BooleanValue::has_value() const {
  return (_has_bits_[0] & 0x00000001u) != 0;
}
inline void BooleanValue::set_has_value() {
  _has_bits_[0] |= 0x00000001u;
}
inline void BooleanValue::clear_has_value() {
  _has_bits_[0] &= ~0x00000001u;
}
inline void BooleanValue::clear_value() {
  value_ = false;
  clear_has_value();
}
inline bool BooleanValue::value() const {
  // @@protoc_insertion_point(field_get:json_proto.BooleanValue.value)
  return value_;
}
inline void BooleanValue::set_value(bool value) {
  set_has_value();
  value_ = value;
  // @@protoc_insertion_point(field_set:json_proto.BooleanValue.value)
}

#endif  // !PROTOBUF_INLINE_NOT_IN_HEADERS
// -------------------------------------------------------------------

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

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

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

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

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

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

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

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


// @@protoc_insertion_point(namespace_scope)


}  // namespace json_proto

// @@protoc_insertion_point(global_scope)

#endif  // PROTOBUF_json_2eproto__INCLUDED
