// _gen/display/pretty.asdl.h is generated by asdl_main.py

#ifndef PRETTY_ASDL
#define PRETTY_ASDL

#include <cstdint>
#include "mycpp/runtime.h"

#include "asdl/cpp_runtime.h"
namespace pretty_asdl {

// use struct instead of namespace so 'using' works consistently
#define ASDL_NAMES struct

class MeasuredDoc;
class Measure;
class doc_t;
class DocFragment;

ASDL_NAMES doc_e {
  enum no_name {
  Break = 1,
  Text = 2,
  Indent = 3,
  Group = 64,
  Flat = 5,
  IfFlat = 6,
  Concat = 66,
  };
};

BigStr* doc_str(int tag, bool dot = true);

class doc_t {
 protected:
  doc_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  DISALLOW_COPY_AND_ASSIGN(doc_t)
};

class doc__Break : public doc_t {
 public:
  doc__Break(BigStr* string)
      : string(string) {
  }

  static doc__Break* CreateNull(bool alloc_lists = false) { 
    return Alloc<doc__Break>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(doc_e::Break), 1);
  }
  BigStr* string;

  DISALLOW_COPY_AND_ASSIGN(doc__Break)
};

class doc__Text : public doc_t {
 public:
  doc__Text(BigStr* string)
      : string(string) {
  }

  static doc__Text* CreateNull(bool alloc_lists = false) { 
    return Alloc<doc__Text>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(doc_e::Text), 1);
  }
  BigStr* string;

  DISALLOW_COPY_AND_ASSIGN(doc__Text)
};

class doc__Indent : public doc_t {
 public:
  doc__Indent(int indent, MeasuredDoc* mdoc)
      : mdoc(mdoc),
        indent(indent) {
  }

  static doc__Indent* CreateNull(bool alloc_lists = false) { 
    return Alloc<doc__Indent>(-1, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(doc_e::Indent), 1);
  }
  MeasuredDoc* mdoc;
  int indent;

  DISALLOW_COPY_AND_ASSIGN(doc__Indent)
};

class doc__Flat : public doc_t {
 public:
  doc__Flat(MeasuredDoc* mdoc)
      : mdoc(mdoc) {
  }

  static doc__Flat* CreateNull(bool alloc_lists = false) { 
    return Alloc<doc__Flat>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(doc_e::Flat), 1);
  }
  MeasuredDoc* mdoc;

  DISALLOW_COPY_AND_ASSIGN(doc__Flat)
};

class doc__IfFlat : public doc_t {
 public:
  doc__IfFlat(MeasuredDoc* flat_mdoc, MeasuredDoc* nonflat_mdoc)
      : flat_mdoc(flat_mdoc),
        nonflat_mdoc(nonflat_mdoc) {
  }

  static doc__IfFlat* CreateNull(bool alloc_lists = false) { 
    return Alloc<doc__IfFlat>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(doc_e::IfFlat), 2);
  }
  MeasuredDoc* flat_mdoc;
  MeasuredDoc* nonflat_mdoc;

  DISALLOW_COPY_AND_ASSIGN(doc__IfFlat)
};

ASDL_NAMES doc {
  typedef doc__Break Break;
  typedef doc__Text Text;
  typedef doc__Indent Indent;
  typedef doc__Flat Flat;
  typedef doc__IfFlat IfFlat;
};

class MeasuredDoc : public doc_t {
 public:
  MeasuredDoc(doc_t* doc, Measure* measure)
      : doc(doc),
        measure(measure) {
  }

  static MeasuredDoc* CreateNull(bool alloc_lists = false) { 
    return Alloc<MeasuredDoc>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(64, 2);
  }
  doc_t* doc;
  Measure* measure;

  DISALLOW_COPY_AND_ASSIGN(MeasuredDoc)
};

class Measure {
 public:
  Measure(int flat, int nonflat)
      : flat(flat),
        nonflat(nonflat) {
  }

  static Measure* CreateNull(bool alloc_lists = false) { 
    return Alloc<Measure>(-1, -1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(65, 0);
  }
  int flat;
  int nonflat;

  DISALLOW_COPY_AND_ASSIGN(Measure)
};

class DocFragment {
 public:
  DocFragment(MeasuredDoc* mdoc, int indent, bool is_flat, Measure* measure)
      : mdoc(mdoc),
        measure(measure),
        indent(indent),
        is_flat(is_flat) {
  }

  static DocFragment* CreateNull(bool alloc_lists = false) { 
    return Alloc<DocFragment>(nullptr, -1, false, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(67, 2);
  }
  MeasuredDoc* mdoc;
  Measure* measure;
  int indent;
  bool is_flat;

  DISALLOW_COPY_AND_ASSIGN(DocFragment)
};

class List_Measured : public doc_t, public List<MeasuredDoc*> {
 public:
  List_Measured() : List<MeasuredDoc*>() {
  }
  List_Measured(List<MeasuredDoc*>* plain_list) :
                List<MeasuredDoc*>(plain_list) {
  }
  static List_Measured* New() {
    return Alloc<List_Measured>();
  }
  static List_Measured* Take(List<MeasuredDoc*>* plain_list) {
    auto* result = Alloc<List_Measured>(plain_list);
    plain_list->SetTaken();
    return result;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  
  static constexpr ObjHeader obj_header() {
    return ObjHeader::TaggedSubtype(66, field_mask());
  }
  DISALLOW_COPY_AND_ASSIGN(List_Measured)
};


}  // namespace pretty_asdl

#endif  // PRETTY_ASDL
