// Generated by Cap'n Proto compiler, DO NOT EDIT
// source: json.capnp

#pragma once

#include <capnp/generated-header-support.h>
#include <kj/windows-sanity.h>
#if !CAPNP_LITE
#include <capnp/capability.h>
#endif  // !CAPNP_LITE

#if CAPNP_VERSION != 10002
#error "Version mismatch between generated code and library headers.  You must use the same version of the Cap'n Proto compiler and library."
#endif


CAPNP_BEGIN_HEADER

namespace capnp {
namespace schemas {

CAPNP_DECLARE_SCHEMA(a3fa7845f919dd83);
CAPNP_DECLARE_SCHEMA(e31026e735d69ddf);
CAPNP_DECLARE_SCHEMA(a0d9f6eca1c93d48);
CAPNP_DECLARE_SCHEMA(fa5b1fd61c2e7c3d);
CAPNP_DECLARE_SCHEMA(82d3e852af0336bf);
CAPNP_DECLARE_SCHEMA(c4df13257bc2ea61);
CAPNP_DECLARE_SCHEMA(cfa794e8d19a0162);
CAPNP_DECLARE_SCHEMA(c2f8c20c293e5319);
CAPNP_DECLARE_SCHEMA(d7d879450a253e4b);
CAPNP_DECLARE_SCHEMA(f061e22f0ae5c7b5);
CAPNP_DECLARE_SCHEMA(a0a054dea32fd98c);

}  // namespace schemas
}  // namespace capnp

namespace capnp {
namespace json {

struct Value {
  Value() = delete;

  class Reader;
  class Builder;
  class Pipeline;
  enum Which: uint16_t {
    NULL_,
    BOOLEAN,
    NUMBER,
    STRING,
    ARRAY,
    OBJECT,
    CALL,
  };
  struct Field;
  struct Call;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(a3fa7845f919dd83, 2, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Value::Field {
  Field() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(e31026e735d69ddf, 0, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct Value::Call {
  Call() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(a0d9f6eca1c93d48, 0, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct FlattenOptions {
  FlattenOptions() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(c4df13257bc2ea61, 0, 1)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

struct DiscriminatorOptions {
  DiscriminatorOptions() = delete;

  class Reader;
  class Builder;
  class Pipeline;

  struct _capnpPrivate {
    CAPNP_DECLARE_STRUCT_HEADER(c2f8c20c293e5319, 0, 2)
    #if !CAPNP_LITE
    static constexpr ::capnp::_::RawBrandedSchema const* brand() { return &schema->defaultBrand; }
    #endif  // !CAPNP_LITE
  };
};

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

class Value::Reader {
public:
  typedef Value Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

  inline ::capnp::MessageSize totalSize() const {
    return _reader.totalSize().asPublic();
  }

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline Which which() const;
  inline bool isNull() const;
  inline  ::capnp::Void getNull() const;

  inline bool isBoolean() const;
  inline bool getBoolean() const;

  inline bool isNumber() const;
  inline double getNumber() const;

  inline bool isString() const;
  inline bool hasString() const;
  inline  ::capnp::Text::Reader getString() const;

  inline bool isArray() const;
  inline bool hasArray() const;
  inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader getArray() const;

  inline bool isObject() const;
  inline bool hasObject() const;
  inline  ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Reader getObject() const;

  inline bool isCall() const;
  inline bool hasCall() const;
  inline  ::capnp::json::Value::Call::Reader getCall() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class Value::Builder {
public:
  typedef Value Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline Which which();
  inline bool isNull();
  inline  ::capnp::Void getNull();
  inline void setNull( ::capnp::Void value = ::capnp::VOID);

  inline bool isBoolean();
  inline bool getBoolean();
  inline void setBoolean(bool value);

  inline bool isNumber();
  inline double getNumber();
  inline void setNumber(double value);

  inline bool isString();
  inline bool hasString();
  inline  ::capnp::Text::Builder getString();
  inline void setString( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initString(unsigned int size);
  inline void adoptString(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownString();

  inline bool isArray();
  inline bool hasArray();
  inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder getArray();
  inline void setArray( ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader value);
  inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder initArray(unsigned int size);
  inline void adoptArray(::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>&& value);
  inline ::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>> disownArray();

  inline bool isObject();
  inline bool hasObject();
  inline  ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Builder getObject();
  inline void setObject( ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Reader value);
  inline  ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Builder initObject(unsigned int size);
  inline void adoptObject(::capnp::Orphan< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>&& value);
  inline ::capnp::Orphan< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>> disownObject();

  inline bool isCall();
  inline bool hasCall();
  inline  ::capnp::json::Value::Call::Builder getCall();
  inline void setCall( ::capnp::json::Value::Call::Reader value);
  inline  ::capnp::json::Value::Call::Builder initCall();
  inline void adoptCall(::capnp::Orphan< ::capnp::json::Value::Call>&& value);
  inline ::capnp::Orphan< ::capnp::json::Value::Call> disownCall();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

#if !CAPNP_LITE
class Value::Pipeline {
public:
  typedef Value Pipelines;

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class Value::Field::Reader {
public:
  typedef Field Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

  inline ::capnp::MessageSize totalSize() const {
    return _reader.totalSize().asPublic();
  }

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasName() const;
  inline  ::capnp::Text::Reader getName() const;

  inline bool hasValue() const;
  inline  ::capnp::json::Value::Reader getValue() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class Value::Field::Builder {
public:
  typedef Field Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasName();
  inline  ::capnp::Text::Builder getName();
  inline void setName( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initName(unsigned int size);
  inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownName();

  inline bool hasValue();
  inline  ::capnp::json::Value::Builder getValue();
  inline void setValue( ::capnp::json::Value::Reader value);
  inline  ::capnp::json::Value::Builder initValue();
  inline void adoptValue(::capnp::Orphan< ::capnp::json::Value>&& value);
  inline ::capnp::Orphan< ::capnp::json::Value> disownValue();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

#if !CAPNP_LITE
class Value::Field::Pipeline {
public:
  typedef Field Pipelines;

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

  inline  ::capnp::json::Value::Pipeline getValue();
private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class Value::Call::Reader {
public:
  typedef Call Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

  inline ::capnp::MessageSize totalSize() const {
    return _reader.totalSize().asPublic();
  }

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasFunction() const;
  inline  ::capnp::Text::Reader getFunction() const;

  inline bool hasParams() const;
  inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader getParams() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class Value::Call::Builder {
public:
  typedef Call Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasFunction();
  inline  ::capnp::Text::Builder getFunction();
  inline void setFunction( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initFunction(unsigned int size);
  inline void adoptFunction(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownFunction();

  inline bool hasParams();
  inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder getParams();
  inline void setParams( ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader value);
  inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder initParams(unsigned int size);
  inline void adoptParams(::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>&& value);
  inline ::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>> disownParams();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

#if !CAPNP_LITE
class Value::Call::Pipeline {
public:
  typedef Call Pipelines;

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class FlattenOptions::Reader {
public:
  typedef FlattenOptions Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

  inline ::capnp::MessageSize totalSize() const {
    return _reader.totalSize().asPublic();
  }

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasPrefix() const;
  inline  ::capnp::Text::Reader getPrefix() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class FlattenOptions::Builder {
public:
  typedef FlattenOptions Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasPrefix();
  inline  ::capnp::Text::Builder getPrefix();
  inline void setPrefix( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initPrefix(unsigned int size);
  inline void adoptPrefix(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownPrefix();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

#if !CAPNP_LITE
class FlattenOptions::Pipeline {
public:
  typedef FlattenOptions Pipelines;

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

class DiscriminatorOptions::Reader {
public:
  typedef DiscriminatorOptions Reads;

  Reader() = default;
  inline explicit Reader(::capnp::_::StructReader base): _reader(base) {}

  inline ::capnp::MessageSize totalSize() const {
    return _reader.totalSize().asPublic();
  }

#if !CAPNP_LITE
  inline ::kj::StringTree toString() const {
    return ::capnp::_::structString(_reader, *_capnpPrivate::brand());
  }
#endif  // !CAPNP_LITE

  inline bool hasName() const;
  inline  ::capnp::Text::Reader getName() const;

  inline bool hasValueName() const;
  inline  ::capnp::Text::Reader getValueName() const;

private:
  ::capnp::_::StructReader _reader;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::List;
  friend class ::capnp::MessageBuilder;
  friend class ::capnp::Orphanage;
};

class DiscriminatorOptions::Builder {
public:
  typedef DiscriminatorOptions Builds;

  Builder() = delete;  // Deleted to discourage incorrect usage.
                       // You can explicitly initialize to nullptr instead.
  inline Builder(decltype(nullptr)) {}
  inline explicit Builder(::capnp::_::StructBuilder base): _builder(base) {}
  inline operator Reader() const { return Reader(_builder.asReader()); }
  inline Reader asReader() const { return *this; }

  inline ::capnp::MessageSize totalSize() const { return asReader().totalSize(); }
#if !CAPNP_LITE
  inline ::kj::StringTree toString() const { return asReader().toString(); }
#endif  // !CAPNP_LITE

  inline bool hasName();
  inline  ::capnp::Text::Builder getName();
  inline void setName( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initName(unsigned int size);
  inline void adoptName(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownName();

  inline bool hasValueName();
  inline  ::capnp::Text::Builder getValueName();
  inline void setValueName( ::capnp::Text::Reader value);
  inline  ::capnp::Text::Builder initValueName(unsigned int size);
  inline void adoptValueName(::capnp::Orphan< ::capnp::Text>&& value);
  inline ::capnp::Orphan< ::capnp::Text> disownValueName();

private:
  ::capnp::_::StructBuilder _builder;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
  friend class ::capnp::Orphanage;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::_::PointerHelpers;
};

#if !CAPNP_LITE
class DiscriminatorOptions::Pipeline {
public:
  typedef DiscriminatorOptions Pipelines;

  inline Pipeline(decltype(nullptr)): _typeless(nullptr) {}
  inline explicit Pipeline(::capnp::AnyPointer::Pipeline&& typeless)
      : _typeless(kj::mv(typeless)) {}

private:
  ::capnp::AnyPointer::Pipeline _typeless;
  friend class ::capnp::PipelineHook;
  template <typename, ::capnp::Kind>
  friend struct ::capnp::ToDynamic_;
};
#endif  // !CAPNP_LITE

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

inline  ::capnp::json::Value::Which Value::Reader::which() const {
  return _reader.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline  ::capnp::json::Value::Which Value::Builder::which() {
  return _builder.getDataField<Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline bool Value::Reader::isNull() const {
  return which() == Value::NULL_;
}
inline bool Value::Builder::isNull() {
  return which() == Value::NULL_;
}
inline  ::capnp::Void Value::Reader::getNull() const {
  KJ_IREQUIRE((which() == Value::NULL_),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}

inline  ::capnp::Void Value::Builder::getNull() {
  KJ_IREQUIRE((which() == Value::NULL_),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS);
}
inline void Value::Builder::setNull( ::capnp::Void value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::NULL_);
  _builder.setDataField< ::capnp::Void>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, value);
}

inline bool Value::Reader::isBoolean() const {
  return which() == Value::BOOLEAN;
}
inline bool Value::Builder::isBoolean() {
  return which() == Value::BOOLEAN;
}
inline bool Value::Reader::getBoolean() const {
  KJ_IREQUIRE((which() == Value::BOOLEAN),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField<bool>(
      ::capnp::bounded<16>() * ::capnp::ELEMENTS);
}

inline bool Value::Builder::getBoolean() {
  KJ_IREQUIRE((which() == Value::BOOLEAN),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField<bool>(
      ::capnp::bounded<16>() * ::capnp::ELEMENTS);
}
inline void Value::Builder::setBoolean(bool value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::BOOLEAN);
  _builder.setDataField<bool>(
      ::capnp::bounded<16>() * ::capnp::ELEMENTS, value);
}

inline bool Value::Reader::isNumber() const {
  return which() == Value::NUMBER;
}
inline bool Value::Builder::isNumber() {
  return which() == Value::NUMBER;
}
inline double Value::Reader::getNumber() const {
  KJ_IREQUIRE((which() == Value::NUMBER),
              "Must check which() before get()ing a union member.");
  return _reader.getDataField<double>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}

inline double Value::Builder::getNumber() {
  KJ_IREQUIRE((which() == Value::NUMBER),
              "Must check which() before get()ing a union member.");
  return _builder.getDataField<double>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS);
}
inline void Value::Builder::setNumber(double value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::NUMBER);
  _builder.setDataField<double>(
      ::capnp::bounded<1>() * ::capnp::ELEMENTS, value);
}

inline bool Value::Reader::isString() const {
  return which() == Value::STRING;
}
inline bool Value::Builder::isString() {
  return which() == Value::STRING;
}
inline bool Value::Reader::hasString() const {
  if (which() != Value::STRING) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Builder::hasString() {
  if (which() != Value::STRING) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader Value::Reader::getString() const {
  KJ_IREQUIRE((which() == Value::STRING),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder Value::Builder::getString() {
  KJ_IREQUIRE((which() == Value::STRING),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Builder::setString( ::capnp::Text::Reader value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::STRING);
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder Value::Builder::initString(unsigned int size) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::STRING);
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void Value::Builder::adoptString(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::STRING);
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> Value::Builder::disownString() {
  KJ_IREQUIRE((which() == Value::STRING),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Value::Reader::isArray() const {
  return which() == Value::ARRAY;
}
inline bool Value::Builder::isArray() {
  return which() == Value::ARRAY;
}
inline bool Value::Reader::hasArray() const {
  if (which() != Value::ARRAY) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Builder::hasArray() {
  if (which() != Value::ARRAY) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader Value::Reader::getArray() const {
  KJ_IREQUIRE((which() == Value::ARRAY),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder Value::Builder::getArray() {
  KJ_IREQUIRE((which() == Value::ARRAY),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Builder::setArray( ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ARRAY);
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder Value::Builder::initArray(unsigned int size) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ARRAY);
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void Value::Builder::adoptArray(
    ::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>&& value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::ARRAY);
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>> Value::Builder::disownArray() {
  KJ_IREQUIRE((which() == Value::ARRAY),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Value::Reader::isObject() const {
  return which() == Value::OBJECT;
}
inline bool Value::Builder::isObject() {
  return which() == Value::OBJECT;
}
inline bool Value::Reader::hasObject() const {
  if (which() != Value::OBJECT) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Builder::hasObject() {
  if (which() != Value::OBJECT) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Reader Value::Reader::getObject() const {
  KJ_IREQUIRE((which() == Value::OBJECT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Builder Value::Builder::getObject() {
  KJ_IREQUIRE((which() == Value::OBJECT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Builder::setObject( ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Reader value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::OBJECT);
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>::Builder Value::Builder::initObject(unsigned int size) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::OBJECT);
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void Value::Builder::adoptObject(
    ::capnp::Orphan< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>&& value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::OBJECT);
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>> Value::Builder::disownObject() {
  KJ_IREQUIRE((which() == Value::OBJECT),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value::Field,  ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Value::Reader::isCall() const {
  return which() == Value::CALL;
}
inline bool Value::Builder::isCall() {
  return which() == Value::CALL;
}
inline bool Value::Reader::hasCall() const {
  if (which() != Value::CALL) return false;
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Builder::hasCall() {
  if (which() != Value::CALL) return false;
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::json::Value::Call::Reader Value::Reader::getCall() const {
  KJ_IREQUIRE((which() == Value::CALL),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::json::Value::Call>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::json::Value::Call::Builder Value::Builder::getCall() {
  KJ_IREQUIRE((which() == Value::CALL),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::json::Value::Call>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Builder::setCall( ::capnp::json::Value::Call::Reader value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::CALL);
  ::capnp::_::PointerHelpers< ::capnp::json::Value::Call>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::json::Value::Call::Builder Value::Builder::initCall() {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::CALL);
  return ::capnp::_::PointerHelpers< ::capnp::json::Value::Call>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Builder::adoptCall(
    ::capnp::Orphan< ::capnp::json::Value::Call>&& value) {
  _builder.setDataField<Value::Which>(
      ::capnp::bounded<0>() * ::capnp::ELEMENTS, Value::CALL);
  ::capnp::_::PointerHelpers< ::capnp::json::Value::Call>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::json::Value::Call> Value::Builder::disownCall() {
  KJ_IREQUIRE((which() == Value::CALL),
              "Must check which() before get()ing a union member.");
  return ::capnp::_::PointerHelpers< ::capnp::json::Value::Call>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Value::Field::Reader::hasName() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Field::Builder::hasName() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader Value::Field::Reader::getName() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder Value::Field::Builder::getName() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Field::Builder::setName( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder Value::Field::Builder::initName(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void Value::Field::Builder::adoptName(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> Value::Field::Builder::disownName() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Value::Field::Reader::hasValue() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Field::Builder::hasValue() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::json::Value::Reader Value::Field::Reader::getValue() const {
  return ::capnp::_::PointerHelpers< ::capnp::json::Value>::get(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline  ::capnp::json::Value::Builder Value::Field::Builder::getValue() {
  return ::capnp::_::PointerHelpers< ::capnp::json::Value>::get(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
#if !CAPNP_LITE
inline  ::capnp::json::Value::Pipeline Value::Field::Pipeline::getValue() {
  return  ::capnp::json::Value::Pipeline(_typeless.getPointerField(1));
}
#endif  // !CAPNP_LITE
inline void Value::Field::Builder::setValue( ::capnp::json::Value::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::json::Value>::set(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline  ::capnp::json::Value::Builder Value::Field::Builder::initValue() {
  return ::capnp::_::PointerHelpers< ::capnp::json::Value>::init(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void Value::Field::Builder::adoptValue(
    ::capnp::Orphan< ::capnp::json::Value>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::json::Value>::adopt(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::json::Value> Value::Field::Builder::disownValue() {
  return ::capnp::_::PointerHelpers< ::capnp::json::Value>::disown(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}

inline bool Value::Call::Reader::hasFunction() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Call::Builder::hasFunction() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader Value::Call::Reader::getFunction() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder Value::Call::Builder::getFunction() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void Value::Call::Builder::setFunction( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder Value::Call::Builder::initFunction(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void Value::Call::Builder::adoptFunction(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> Value::Call::Builder::disownFunction() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool Value::Call::Reader::hasParams() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool Value::Call::Builder::hasParams() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader Value::Call::Reader::getParams() const {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::get(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder Value::Call::Builder::getParams() {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::get(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void Value::Call::Builder::setParams( ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::set(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline  ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>::Builder Value::Call::Builder::initParams(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::init(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void Value::Call::Builder::adoptParams(
    ::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::adopt(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>> Value::Call::Builder::disownParams() {
  return ::capnp::_::PointerHelpers< ::capnp::List< ::capnp::json::Value,  ::capnp::Kind::STRUCT>>::disown(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}

inline bool FlattenOptions::Reader::hasPrefix() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool FlattenOptions::Builder::hasPrefix() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader FlattenOptions::Reader::getPrefix() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS),
        ::capnp::schemas::bp_c4df13257bc2ea61 + 34);
}
inline  ::capnp::Text::Builder FlattenOptions::Builder::getPrefix() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS),
        ::capnp::schemas::bp_c4df13257bc2ea61 + 34);
}
inline void FlattenOptions::Builder::setPrefix( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder FlattenOptions::Builder::initPrefix(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void FlattenOptions::Builder::adoptPrefix(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> FlattenOptions::Builder::disownPrefix() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool DiscriminatorOptions::Reader::hasName() const {
  return !_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline bool DiscriminatorOptions::Builder::hasName() {
  return !_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader DiscriminatorOptions::Reader::getName() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder DiscriminatorOptions::Builder::getName() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}
inline void DiscriminatorOptions::Builder::setName( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder DiscriminatorOptions::Builder::initName(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), size);
}
inline void DiscriminatorOptions::Builder::adoptName(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> DiscriminatorOptions::Builder::disownName() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<0>() * ::capnp::POINTERS));
}

inline bool DiscriminatorOptions::Reader::hasValueName() const {
  return !_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline bool DiscriminatorOptions::Builder::hasValueName() {
  return !_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS).isNull();
}
inline  ::capnp::Text::Reader DiscriminatorOptions::Reader::getValueName() const {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_reader.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline  ::capnp::Text::Builder DiscriminatorOptions::Builder::getValueName() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::get(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}
inline void DiscriminatorOptions::Builder::setValueName( ::capnp::Text::Reader value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::set(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), value);
}
inline  ::capnp::Text::Builder DiscriminatorOptions::Builder::initValueName(unsigned int size) {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::init(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), size);
}
inline void DiscriminatorOptions::Builder::adoptValueName(
    ::capnp::Orphan< ::capnp::Text>&& value) {
  ::capnp::_::PointerHelpers< ::capnp::Text>::adopt(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS), kj::mv(value));
}
inline ::capnp::Orphan< ::capnp::Text> DiscriminatorOptions::Builder::disownValueName() {
  return ::capnp::_::PointerHelpers< ::capnp::Text>::disown(_builder.getPointerField(
      ::capnp::bounded<1>() * ::capnp::POINTERS));
}

}  // namespace
}  // namespace

CAPNP_END_HEADER

