//===--- JSONNodeDumper.h - Printing of AST nodes to JSON -----------------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements AST dumping of components of individual AST nodes to
// a JSON.
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_CLANG_AST_JSONNODEDUMPER_H
#define LLVM_CLANG_AST_JSONNODEDUMPER_H

#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTNodeTraverser.h"
#include "clang/AST/ASTDumperUtils.h"
#include "clang/AST/AttrVisitor.h"
#include "clang/AST/CommentCommandTraits.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/AST/ExprCXX.h"
#include "llvm/Support/JSON.h"

namespace clang {

class NodeStreamer {
  bool FirstChild = true;
  bool TopLevel = true;
  llvm::SmallVector<std::function<void(bool IsLastChild)>, 32> Pending;

protected:
  llvm::json::OStream JOS;

public:
  /// Add a child of the current node.  Calls DoAddChild without arguments
  template <typename Fn> void AddChild(Fn DoAddChild) {
    return AddChild("", DoAddChild);
  }

  /// Add a child of the current node with an optional label.
  /// Calls DoAddChild without arguments.
  template <typename Fn> void AddChild(StringRef Label, Fn DoAddChild) {
    // If we're at the top level, there's nothing interesting to do; just
    // run the dumper.
    if (TopLevel) {
      TopLevel = false;
      JOS.objectBegin();

      DoAddChild();

      while (!Pending.empty()) {
        Pending.back()(true);
        Pending.pop_back();
      }

      JOS.objectEnd();
      TopLevel = true;
      return;
    }

    // We need to capture an owning-string in the lambda because the lambda
    // is invoked in a deferred manner.
    std::string LabelStr = !Label.empty() ? Label : "inner";
    bool WasFirstChild = FirstChild;
    auto DumpWithIndent = [=](bool IsLastChild) {
      if (WasFirstChild) {
        JOS.attributeBegin(LabelStr);
        JOS.arrayBegin();
      }

      FirstChild = true;
      unsigned Depth = Pending.size();
      JOS.objectBegin();

      DoAddChild();

      // If any children are left, they're the last at their nesting level.
      // Dump those ones out now.
      while (Depth < Pending.size()) {
        Pending.back()(true);
        this->Pending.pop_back();
      }

      JOS.objectEnd();

      if (IsLastChild) {
        JOS.arrayEnd();
        JOS.attributeEnd();
      }
    };

    if (FirstChild) {
      Pending.push_back(std::move(DumpWithIndent));
    } else {
      Pending.back()(false);
      Pending.back() = std::move(DumpWithIndent);
    }
    FirstChild = false;
  }

  NodeStreamer(raw_ostream &OS) : JOS(OS, 2) {}
};

// Dumps AST nodes in JSON format. There is no implied stability for the
// content or format of the dump between major releases of Clang, other than it
// being valid JSON output. Further, there is no requirement that the
// information dumped is a complete representation of the AST, only that the
// information presented is correct.
class JSONNodeDumper
    : public ConstAttrVisitor<JSONNodeDumper>,
      public comments::ConstCommentVisitor<JSONNodeDumper, void,
                                           const comments::FullComment *>,
      public ConstTemplateArgumentVisitor<JSONNodeDumper>,
      public ConstStmtVisitor<JSONNodeDumper>,
      public TypeVisitor<JSONNodeDumper>,
      public ConstDeclVisitor<JSONNodeDumper>,
      public NodeStreamer {
  friend class JSONDumper;

  const SourceManager &SM;
  ASTContext& Ctx;
  PrintingPolicy PrintPolicy;
  const comments::CommandTraits *Traits;
  StringRef LastLocFilename;
  unsigned LastLocLine;

  using InnerAttrVisitor = ConstAttrVisitor<JSONNodeDumper>;
  using InnerCommentVisitor =
      comments::ConstCommentVisitor<JSONNodeDumper, void,
                                    const comments::FullComment *>;
  using InnerTemplateArgVisitor = ConstTemplateArgumentVisitor<JSONNodeDumper>;
  using InnerStmtVisitor = ConstStmtVisitor<JSONNodeDumper>;
  using InnerTypeVisitor = TypeVisitor<JSONNodeDumper>;
  using InnerDeclVisitor = ConstDeclVisitor<JSONNodeDumper>;

  void attributeOnlyIfTrue(StringRef Key, bool Value) {
    if (Value)
      JOS.attribute(Key, Value);
  }

  // Writes the attributes of a SourceLocation object without.
  void writeBareSourceLocation(SourceLocation Loc);

  // Writes the attributes of a SourceLocation to JSON based on its presumed
  // spelling location. If the given location represents a macro invocation,
  // this outputs two sub-objects: one for the spelling and one for the
  // expansion location.
  void writeSourceLocation(SourceLocation Loc);
  void writeSourceRange(SourceRange R);
  std::string createPointerRepresentation(const void *Ptr);
  llvm::json::Object createQualType(QualType QT, bool Desugar = true);
  llvm::json::Object createBareDeclRef(const Decl *D);
  void writeBareDeclRef(const Decl *D);
  llvm::json::Object createCXXRecordDefinitionData(const CXXRecordDecl *RD);
  llvm::json::Object createCXXBaseSpecifier(const CXXBaseSpecifier &BS);
  std::string createAccessSpecifier(AccessSpecifier AS);
  llvm::json::Array createCastPath(const CastExpr *C);

  void writePreviousDeclImpl(...) {}

  template <typename T> void writePreviousDeclImpl(const Mergeable<T> *D) {
    const T *First = D->getFirstDecl();
    if (First != D)
      JOS.attribute("firstRedecl", createPointerRepresentation(First));
  }

  template <typename T> void writePreviousDeclImpl(const Redeclarable<T> *D) {
    const T *Prev = D->getPreviousDecl();
    if (Prev)
      JOS.attribute("previousDecl", createPointerRepresentation(Prev));
  }
  void addPreviousDeclaration(const Decl *D);

  StringRef getCommentCommandName(unsigned CommandID) const;

public:
  JSONNodeDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
                 const PrintingPolicy &PrintPolicy,
                 const comments::CommandTraits *Traits)
      : NodeStreamer(OS), SM(SrcMgr), Ctx(Ctx), PrintPolicy(PrintPolicy),
        Traits(Traits), LastLocLine(0) {}

  void Visit(const Attr *A);
  void Visit(const Stmt *Node);
  void Visit(const Type *T);
  void Visit(QualType T);
  void Visit(const Decl *D);

  void Visit(const comments::Comment *C, const comments::FullComment *FC);
  void Visit(const TemplateArgument &TA, SourceRange R = {},
             const Decl *From = nullptr, StringRef Label = {});
  void Visit(const CXXCtorInitializer *Init);
  void Visit(const OMPClause *C);
  void Visit(const BlockDecl::Capture &C);
  void Visit(const GenericSelectionExpr::ConstAssociation &A);

  void VisitTypedefType(const TypedefType *TT);
  void VisitFunctionType(const FunctionType *T);
  void VisitFunctionProtoType(const FunctionProtoType *T);
  void VisitRValueReferenceType(const ReferenceType *RT);
  void VisitArrayType(const ArrayType *AT);
  void VisitConstantArrayType(const ConstantArrayType *CAT);
  void VisitDependentSizedExtVectorType(const DependentSizedExtVectorType *VT);
  void VisitVectorType(const VectorType *VT);
  void VisitUnresolvedUsingType(const UnresolvedUsingType *UUT);
  void VisitUnaryTransformType(const UnaryTransformType *UTT);
  void VisitTagType(const TagType *TT);
  void VisitTemplateTypeParmType(const TemplateTypeParmType *TTPT);
  void VisitAutoType(const AutoType *AT);
  void VisitTemplateSpecializationType(const TemplateSpecializationType *TST);
  void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
  void VisitObjCInterfaceType(const ObjCInterfaceType *OIT);
  void VisitPackExpansionType(const PackExpansionType *PET);
  void VisitElaboratedType(const ElaboratedType *ET);
  void VisitMacroQualifiedType(const MacroQualifiedType *MQT);
  void VisitMemberPointerType(const MemberPointerType *MPT);

  void VisitNamedDecl(const NamedDecl *ND);
  void VisitTypedefDecl(const TypedefDecl *TD);
  void VisitTypeAliasDecl(const TypeAliasDecl *TAD);
  void VisitNamespaceDecl(const NamespaceDecl *ND);
  void VisitUsingDirectiveDecl(const UsingDirectiveDecl *UDD);
  void VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD);
  void VisitUsingDecl(const UsingDecl *UD);
  void VisitUsingShadowDecl(const UsingShadowDecl *USD);
  void VisitVarDecl(const VarDecl *VD);
  void VisitFieldDecl(const FieldDecl *FD);
  void VisitFunctionDecl(const FunctionDecl *FD);
  void VisitEnumDecl(const EnumDecl *ED);
  void VisitEnumConstantDecl(const EnumConstantDecl *ECD);
  void VisitRecordDecl(const RecordDecl *RD);
  void VisitCXXRecordDecl(const CXXRecordDecl *RD);
  void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *D);
  void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *D);
  void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *D);
  void VisitLinkageSpecDecl(const LinkageSpecDecl *LSD);
  void VisitAccessSpecDecl(const AccessSpecDecl *ASD);
  void VisitFriendDecl(const FriendDecl *FD);

  void VisitObjCIvarDecl(const ObjCIvarDecl *D);
  void VisitObjCMethodDecl(const ObjCMethodDecl *D);
  void VisitObjCTypeParamDecl(const ObjCTypeParamDecl *D);
  void VisitObjCCategoryDecl(const ObjCCategoryDecl *D);
  void VisitObjCCategoryImplDecl(const ObjCCategoryImplDecl *D);
  void VisitObjCProtocolDecl(const ObjCProtocolDecl *D);
  void VisitObjCInterfaceDecl(const ObjCInterfaceDecl *D);
  void VisitObjCImplementationDecl(const ObjCImplementationDecl *D);
  void VisitObjCCompatibleAliasDecl(const ObjCCompatibleAliasDecl *D);
  void VisitObjCPropertyDecl(const ObjCPropertyDecl *D);
  void VisitObjCPropertyImplDecl(const ObjCPropertyImplDecl *D);
  void VisitBlockDecl(const BlockDecl *D);

  void VisitDeclRefExpr(const DeclRefExpr *DRE);
  void VisitPredefinedExpr(const PredefinedExpr *PE);
  void VisitUnaryOperator(const UnaryOperator *UO);
  void VisitBinaryOperator(const BinaryOperator *BO);
  void VisitCompoundAssignOperator(const CompoundAssignOperator *CAO);
  void VisitMemberExpr(const MemberExpr *ME);
  void VisitCXXNewExpr(const CXXNewExpr *NE);
  void VisitCXXDeleteExpr(const CXXDeleteExpr *DE);
  void VisitCXXThisExpr(const CXXThisExpr *TE);
  void VisitCastExpr(const CastExpr *CE);
  void VisitImplicitCastExpr(const ImplicitCastExpr *ICE);
  void VisitCallExpr(const CallExpr *CE);
  void VisitUnaryExprOrTypeTraitExpr(const UnaryExprOrTypeTraitExpr *TTE);
  void VisitSizeOfPackExpr(const SizeOfPackExpr *SOPE);
  void VisitUnresolvedLookupExpr(const UnresolvedLookupExpr *ULE);
  void VisitAddrLabelExpr(const AddrLabelExpr *ALE);
  void VisitCXXTypeidExpr(const CXXTypeidExpr *CTE);
  void VisitConstantExpr(const ConstantExpr *CE);
  void VisitInitListExpr(const InitListExpr *ILE);
  void VisitGenericSelectionExpr(const GenericSelectionExpr *GSE);
  void VisitCXXUnresolvedConstructExpr(const CXXUnresolvedConstructExpr *UCE);
  void VisitCXXConstructExpr(const CXXConstructExpr *CE);
  void VisitExprWithCleanups(const ExprWithCleanups *EWC);
  void VisitCXXBindTemporaryExpr(const CXXBindTemporaryExpr *BTE);
  void VisitMaterializeTemporaryExpr(const MaterializeTemporaryExpr *MTE);
  void VisitCXXDependentScopeMemberExpr(const CXXDependentScopeMemberExpr *ME);

  void VisitObjCEncodeExpr(const ObjCEncodeExpr *OEE);
  void VisitObjCMessageExpr(const ObjCMessageExpr *OME);
  void VisitObjCBoxedExpr(const ObjCBoxedExpr *OBE);
  void VisitObjCSelectorExpr(const ObjCSelectorExpr *OSE);
  void VisitObjCProtocolExpr(const ObjCProtocolExpr *OPE);
  void VisitObjCPropertyRefExpr(const ObjCPropertyRefExpr *OPRE);
  void VisitObjCSubscriptRefExpr(const ObjCSubscriptRefExpr *OSRE);
  void VisitObjCIvarRefExpr(const ObjCIvarRefExpr *OIRE);
  void VisitObjCBoolLiteralExpr(const ObjCBoolLiteralExpr *OBLE);

  void VisitIntegerLiteral(const IntegerLiteral *IL);
  void VisitCharacterLiteral(const CharacterLiteral *CL);
  void VisitFixedPointLiteral(const FixedPointLiteral *FPL);
  void VisitFloatingLiteral(const FloatingLiteral *FL);
  void VisitStringLiteral(const StringLiteral *SL);
  void VisitCXXBoolLiteralExpr(const CXXBoolLiteralExpr *BLE);

  void VisitIfStmt(const IfStmt *IS);
  void VisitSwitchStmt(const SwitchStmt *SS);
  void VisitCaseStmt(const CaseStmt *CS);
  void VisitLabelStmt(const LabelStmt *LS);
  void VisitGotoStmt(const GotoStmt *GS);
  void VisitWhileStmt(const WhileStmt *WS);
  void VisitObjCAtCatchStmt(const ObjCAtCatchStmt *OACS);

  void VisitNullTemplateArgument(const TemplateArgument &TA);
  void VisitTypeTemplateArgument(const TemplateArgument &TA);
  void VisitDeclarationTemplateArgument(const TemplateArgument &TA);
  void VisitNullPtrTemplateArgument(const TemplateArgument &TA);
  void VisitIntegralTemplateArgument(const TemplateArgument &TA);
  void VisitTemplateTemplateArgument(const TemplateArgument &TA);
  void VisitTemplateExpansionTemplateArgument(const TemplateArgument &TA);
  void VisitExpressionTemplateArgument(const TemplateArgument &TA);
  void VisitPackTemplateArgument(const TemplateArgument &TA);

  void visitTextComment(const comments::TextComment *C,
                        const comments::FullComment *);
  void visitInlineCommandComment(const comments::InlineCommandComment *C,
                                 const comments::FullComment *);
  void visitHTMLStartTagComment(const comments::HTMLStartTagComment *C,
                                const comments::FullComment *);
  void visitHTMLEndTagComment(const comments::HTMLEndTagComment *C,
                              const comments::FullComment *);
  void visitBlockCommandComment(const comments::BlockCommandComment *C,
                                const comments::FullComment *);
  void visitParamCommandComment(const comments::ParamCommandComment *C,
                                const comments::FullComment *FC);
  void visitTParamCommandComment(const comments::TParamCommandComment *C,
                                 const comments::FullComment *FC);
  void visitVerbatimBlockComment(const comments::VerbatimBlockComment *C,
                                 const comments::FullComment *);
  void
  visitVerbatimBlockLineComment(const comments::VerbatimBlockLineComment *C,
                                const comments::FullComment *);
  void visitVerbatimLineComment(const comments::VerbatimLineComment *C,
                                const comments::FullComment *);
};

class JSONDumper : public ASTNodeTraverser<JSONDumper, JSONNodeDumper> {
  JSONNodeDumper NodeDumper;

  template <typename SpecializationDecl>
  void writeTemplateDeclSpecialization(const SpecializationDecl *SD,
                                       bool DumpExplicitInst,
                                       bool DumpRefOnly) {
    bool DumpedAny = false;
    for (const auto *RedeclWithBadType : SD->redecls()) {
      // FIXME: The redecls() range sometimes has elements of a less-specific
      // type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
      // us TagDecls, and should give CXXRecordDecls).
      const auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
      if (!Redecl) {
        // Found the injected-class-name for a class template. This will be
        // dumped as part of its surrounding class so we don't need to dump it
        // here.
        assert(isa<CXXRecordDecl>(RedeclWithBadType) &&
               "expected an injected-class-name");
        continue;
      }

      switch (Redecl->getTemplateSpecializationKind()) {
      case TSK_ExplicitInstantiationDeclaration:
      case TSK_ExplicitInstantiationDefinition:
        if (!DumpExplicitInst)
          break;
        LLVM_FALLTHROUGH;
      case TSK_Undeclared:
      case TSK_ImplicitInstantiation:
        if (DumpRefOnly)
          NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(Redecl); });
        else
          Visit(Redecl);
        DumpedAny = true;
        break;
      case TSK_ExplicitSpecialization:
        break;
      }
    }

    // Ensure we dump at least one decl for each specialization.
    if (!DumpedAny)
      NodeDumper.AddChild([=] { NodeDumper.writeBareDeclRef(SD); });
  }

  template <typename TemplateDecl>
  void writeTemplateDecl(const TemplateDecl *TD, bool DumpExplicitInst) {
    // FIXME: it would be nice to dump template parameters and specializations
    // to their own named arrays rather than shoving them into the "inner"
    // array. However, template declarations are currently being handled at the
    // wrong "level" of the traversal hierarchy and so it is difficult to
    // achieve without losing information elsewhere.

    dumpTemplateParameters(TD->getTemplateParameters());

    Visit(TD->getTemplatedDecl());

    for (const auto *Child : TD->specializations())
      writeTemplateDeclSpecialization(Child, DumpExplicitInst,
                                      !TD->isCanonicalDecl());
  }

public:
  JSONDumper(raw_ostream &OS, const SourceManager &SrcMgr, ASTContext &Ctx,
             const PrintingPolicy &PrintPolicy,
             const comments::CommandTraits *Traits)
      : NodeDumper(OS, SrcMgr, Ctx, PrintPolicy, Traits) {}

  JSONNodeDumper &doGetNodeDelegate() { return NodeDumper; }

  void VisitFunctionTemplateDecl(const FunctionTemplateDecl *FTD) {
    writeTemplateDecl(FTD, true);
  }
  void VisitClassTemplateDecl(const ClassTemplateDecl *CTD) {
    writeTemplateDecl(CTD, false);
  }
  void VisitVarTemplateDecl(const VarTemplateDecl *VTD) {
    writeTemplateDecl(VTD, false);
  }
};

} // namespace clang

#endif // LLVM_CLANG_AST_JSONNODEDUMPER_H
