//===--- CommentToXML.cpp - Convert comments to XML representation --------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/Index/CommentToXML.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/Attr.h"
#include "clang/AST/Comment.h"
#include "clang/AST/CommentVisitor.h"
#include "clang/Format/Format.h"
#include "clang/Index/USRGeneration.h"
#include "llvm/ADT/StringExtras.h"
#include "llvm/ADT/TinyPtrVector.h"
#include "llvm/Support/raw_ostream.h"

using namespace clang;
using namespace clang::comments;
using namespace clang::index;

namespace {

/// This comparison will sort parameters with valid index by index, then vararg
/// parameters, and invalid (unresolved) parameters last.
class ParamCommandCommentCompareIndex {
public:
  bool operator()(const ParamCommandComment *LHS,
                  const ParamCommandComment *RHS) const {
    unsigned LHSIndex = UINT_MAX;
    unsigned RHSIndex = UINT_MAX;

    if (LHS->isParamIndexValid()) {
      if (LHS->isVarArgParam())
        LHSIndex = UINT_MAX - 1;
      else
        LHSIndex = LHS->getParamIndex();
    }
    if (RHS->isParamIndexValid()) {
      if (RHS->isVarArgParam())
        RHSIndex = UINT_MAX - 1;
      else
        RHSIndex = RHS->getParamIndex();
    }
    return LHSIndex < RHSIndex;
  }
};

/// This comparison will sort template parameters in the following order:
/// \li real template parameters (depth = 1) in index order;
/// \li all other names (depth > 1);
/// \li unresolved names.
class TParamCommandCommentComparePosition {
public:
  bool operator()(const TParamCommandComment *LHS,
                  const TParamCommandComment *RHS) const {
    // Sort unresolved names last.
    if (!LHS->isPositionValid())
      return false;
    if (!RHS->isPositionValid())
      return true;

    if (LHS->getDepth() > 1)
      return false;
    if (RHS->getDepth() > 1)
      return true;

    // Sort template parameters in index order.
    if (LHS->getDepth() == 1 && RHS->getDepth() == 1)
      return LHS->getIndex(0) < RHS->getIndex(0);

    // Leave all other names in source order.
    return true;
  }
};

/// Separate parts of a FullComment.
struct FullCommentParts {
  /// Take a full comment apart and initialize members accordingly.
  FullCommentParts(const FullComment *C,
                   const CommandTraits &Traits);

  const BlockContentComment *Brief;
  const BlockContentComment *Headerfile;
  const ParagraphComment *FirstParagraph;
  SmallVector<const BlockCommandComment *, 4> Returns;
  SmallVector<const ParamCommandComment *, 8> Params;
  SmallVector<const TParamCommandComment *, 4> TParams;
  llvm::TinyPtrVector<const BlockCommandComment *> Exceptions;
  SmallVector<const BlockContentComment *, 8> MiscBlocks;
};

FullCommentParts::FullCommentParts(const FullComment *C,
                                   const CommandTraits &Traits) :
    Brief(nullptr), Headerfile(nullptr), FirstParagraph(nullptr) {
  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
       I != E; ++I) {
    const Comment *Child = *I;
    if (!Child)
      continue;
    switch (Child->getCommentKind()) {
    case Comment::NoCommentKind:
      continue;

    case Comment::ParagraphCommentKind: {
      const ParagraphComment *PC = cast<ParagraphComment>(Child);
      if (PC->isWhitespace())
        break;
      if (!FirstParagraph)
        FirstParagraph = PC;

      MiscBlocks.push_back(PC);
      break;
    }

    case Comment::BlockCommandCommentKind: {
      const BlockCommandComment *BCC = cast<BlockCommandComment>(Child);
      const CommandInfo *Info = Traits.getCommandInfo(BCC->getCommandID());
      if (!Brief && Info->IsBriefCommand) {
        Brief = BCC;
        break;
      }
      if (!Headerfile && Info->IsHeaderfileCommand) {
        Headerfile = BCC;
        break;
      }
      if (Info->IsReturnsCommand) {
        Returns.push_back(BCC);
        break;
      }
      if (Info->IsThrowsCommand) {
        Exceptions.push_back(BCC);
        break;
      }
      MiscBlocks.push_back(BCC);
      break;
    }

    case Comment::ParamCommandCommentKind: {
      const ParamCommandComment *PCC = cast<ParamCommandComment>(Child);
      if (!PCC->hasParamName())
        break;

      if (!PCC->isDirectionExplicit() && !PCC->hasNonWhitespaceParagraph())
        break;

      Params.push_back(PCC);
      break;
    }

    case Comment::TParamCommandCommentKind: {
      const TParamCommandComment *TPCC = cast<TParamCommandComment>(Child);
      if (!TPCC->hasParamName())
        break;

      if (!TPCC->hasNonWhitespaceParagraph())
        break;

      TParams.push_back(TPCC);
      break;
    }

    case Comment::VerbatimBlockCommentKind:
      MiscBlocks.push_back(cast<BlockCommandComment>(Child));
      break;

    case Comment::VerbatimLineCommentKind: {
      const VerbatimLineComment *VLC = cast<VerbatimLineComment>(Child);
      const CommandInfo *Info = Traits.getCommandInfo(VLC->getCommandID());
      if (!Info->IsDeclarationCommand)
        MiscBlocks.push_back(VLC);
      break;
    }

    case Comment::TextCommentKind:
    case Comment::InlineCommandCommentKind:
    case Comment::HTMLStartTagCommentKind:
    case Comment::HTMLEndTagCommentKind:
    case Comment::VerbatimBlockLineCommentKind:
    case Comment::FullCommentKind:
      llvm_unreachable("AST node of this kind can't be a child of "
                       "a FullComment");
    }
  }

  // Sort params in order they are declared in the function prototype.
  // Unresolved parameters are put at the end of the list in the same order
  // they were seen in the comment.
  llvm::stable_sort(Params, ParamCommandCommentCompareIndex());
  llvm::stable_sort(TParams, TParamCommandCommentComparePosition());
}

void printHTMLStartTagComment(const HTMLStartTagComment *C,
                              llvm::raw_svector_ostream &Result) {
  Result << "<" << C->getTagName();

  if (C->getNumAttrs() != 0) {
    for (unsigned i = 0, e = C->getNumAttrs(); i != e; i++) {
      Result << " ";
      const HTMLStartTagComment::Attribute &Attr = C->getAttr(i);
      Result << Attr.Name;
      if (!Attr.Value.empty())
        Result << "=\"" << Attr.Value << "\"";
    }
  }

  if (!C->isSelfClosing())
    Result << ">";
  else
    Result << "/>";
}

class CommentASTToHTMLConverter :
    public ConstCommentVisitor<CommentASTToHTMLConverter> {
public:
  /// \param Str accumulator for HTML.
  CommentASTToHTMLConverter(const FullComment *FC,
                            SmallVectorImpl<char> &Str,
                            const CommandTraits &Traits) :
      FC(FC), Result(Str), Traits(Traits)
  { }

  // Inline content.
  void visitTextComment(const TextComment *C);
  void visitInlineCommandComment(const InlineCommandComment *C);
  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
  void visitHTMLEndTagComment(const HTMLEndTagComment *C);

  // Block content.
  void visitParagraphComment(const ParagraphComment *C);
  void visitBlockCommandComment(const BlockCommandComment *C);
  void visitParamCommandComment(const ParamCommandComment *C);
  void visitTParamCommandComment(const TParamCommandComment *C);
  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
  void visitVerbatimLineComment(const VerbatimLineComment *C);

  void visitFullComment(const FullComment *C);

  // Helpers.

  /// Convert a paragraph that is not a block by itself (an argument to some
  /// command).
  void visitNonStandaloneParagraphComment(const ParagraphComment *C);

  void appendToResultWithHTMLEscaping(StringRef S);

private:
  const FullComment *FC;
  /// Output stream for HTML.
  llvm::raw_svector_ostream Result;

  const CommandTraits &Traits;
};
} // end unnamed namespace

void CommentASTToHTMLConverter::visitTextComment(const TextComment *C) {
  appendToResultWithHTMLEscaping(C->getText());
}

void CommentASTToHTMLConverter::visitInlineCommandComment(
                                  const InlineCommandComment *C) {
  // Nothing to render if no arguments supplied.
  if (C->getNumArgs() == 0)
    return;

  // Nothing to render if argument is empty.
  StringRef Arg0 = C->getArgText(0);
  if (Arg0.empty())
    return;

  switch (C->getRenderKind()) {
  case InlineCommandComment::RenderNormal:
    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
      appendToResultWithHTMLEscaping(C->getArgText(i));
      Result << " ";
    }
    return;

  case InlineCommandComment::RenderBold:
    assert(C->getNumArgs() == 1);
    Result << "<b>";
    appendToResultWithHTMLEscaping(Arg0);
    Result << "</b>";
    return;
  case InlineCommandComment::RenderMonospaced:
    assert(C->getNumArgs() == 1);
    Result << "<tt>";
    appendToResultWithHTMLEscaping(Arg0);
    Result<< "</tt>";
    return;
  case InlineCommandComment::RenderEmphasized:
    assert(C->getNumArgs() == 1);
    Result << "<em>";
    appendToResultWithHTMLEscaping(Arg0);
    Result << "</em>";
    return;
  case InlineCommandComment::RenderAnchor:
    assert(C->getNumArgs() == 1);
    Result << "<span id=\"" << Arg0 << "\"></span>";
    return;
  }
}

void CommentASTToHTMLConverter::visitHTMLStartTagComment(
                                  const HTMLStartTagComment *C) {
  printHTMLStartTagComment(C, Result);
}

void CommentASTToHTMLConverter::visitHTMLEndTagComment(
                                  const HTMLEndTagComment *C) {
  Result << "</" << C->getTagName() << ">";
}

void CommentASTToHTMLConverter::visitParagraphComment(
                                  const ParagraphComment *C) {
  if (C->isWhitespace())
    return;

  Result << "<p>";
  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
       I != E; ++I) {
    visit(*I);
  }
  Result << "</p>";
}

void CommentASTToHTMLConverter::visitBlockCommandComment(
                                  const BlockCommandComment *C) {
  const CommandInfo *Info = Traits.getCommandInfo(C->getCommandID());
  if (Info->IsBriefCommand) {
    Result << "<p class=\"para-brief\">";
    visitNonStandaloneParagraphComment(C->getParagraph());
    Result << "</p>";
    return;
  }
  if (Info->IsReturnsCommand) {
    Result << "<p class=\"para-returns\">"
              "<span class=\"word-returns\">Returns</span> ";
    visitNonStandaloneParagraphComment(C->getParagraph());
    Result << "</p>";
    return;
  }
  // We don't know anything about this command.  Just render the paragraph.
  visit(C->getParagraph());
}

void CommentASTToHTMLConverter::visitParamCommandComment(
                                  const ParamCommandComment *C) {
  if (C->isParamIndexValid()) {
    if (C->isVarArgParam()) {
      Result << "<dt class=\"param-name-index-vararg\">";
      appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
    } else {
      Result << "<dt class=\"param-name-index-"
             << C->getParamIndex()
             << "\">";
      appendToResultWithHTMLEscaping(C->getParamName(FC));
    }
  } else {
    Result << "<dt class=\"param-name-index-invalid\">";
    appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
  }
  Result << "</dt>";

  if (C->isParamIndexValid()) {
    if (C->isVarArgParam())
      Result << "<dd class=\"param-descr-index-vararg\">";
    else
      Result << "<dd class=\"param-descr-index-"
             << C->getParamIndex()
             << "\">";
  } else
    Result << "<dd class=\"param-descr-index-invalid\">";

  visitNonStandaloneParagraphComment(C->getParagraph());
  Result << "</dd>";
}

void CommentASTToHTMLConverter::visitTParamCommandComment(
                                  const TParamCommandComment *C) {
  if (C->isPositionValid()) {
    if (C->getDepth() == 1)
      Result << "<dt class=\"tparam-name-index-"
             << C->getIndex(0)
             << "\">";
    else
      Result << "<dt class=\"tparam-name-index-other\">";
    appendToResultWithHTMLEscaping(C->getParamName(FC));
  } else {
    Result << "<dt class=\"tparam-name-index-invalid\">";
    appendToResultWithHTMLEscaping(C->getParamNameAsWritten());
  }

  Result << "</dt>";

  if (C->isPositionValid()) {
    if (C->getDepth() == 1)
      Result << "<dd class=\"tparam-descr-index-"
             << C->getIndex(0)
             << "\">";
    else
      Result << "<dd class=\"tparam-descr-index-other\">";
  } else
    Result << "<dd class=\"tparam-descr-index-invalid\">";

  visitNonStandaloneParagraphComment(C->getParagraph());
  Result << "</dd>";
}

void CommentASTToHTMLConverter::visitVerbatimBlockComment(
                                  const VerbatimBlockComment *C) {
  unsigned NumLines = C->getNumLines();
  if (NumLines == 0)
    return;

  Result << "<pre>";
  for (unsigned i = 0; i != NumLines; ++i) {
    appendToResultWithHTMLEscaping(C->getText(i));
    if (i + 1 != NumLines)
      Result << '\n';
  }
  Result << "</pre>";
}

void CommentASTToHTMLConverter::visitVerbatimBlockLineComment(
                                  const VerbatimBlockLineComment *C) {
  llvm_unreachable("should not see this AST node");
}

void CommentASTToHTMLConverter::visitVerbatimLineComment(
                                  const VerbatimLineComment *C) {
  Result << "<pre>";
  appendToResultWithHTMLEscaping(C->getText());
  Result << "</pre>";
}

void CommentASTToHTMLConverter::visitFullComment(const FullComment *C) {
  FullCommentParts Parts(C, Traits);

  bool FirstParagraphIsBrief = false;
  if (Parts.Headerfile)
    visit(Parts.Headerfile);
  if (Parts.Brief)
    visit(Parts.Brief);
  else if (Parts.FirstParagraph) {
    Result << "<p class=\"para-brief\">";
    visitNonStandaloneParagraphComment(Parts.FirstParagraph);
    Result << "</p>";
    FirstParagraphIsBrief = true;
  }

  for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
    const Comment *C = Parts.MiscBlocks[i];
    if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
      continue;
    visit(C);
  }

  if (Parts.TParams.size() != 0) {
    Result << "<dl>";
    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
      visit(Parts.TParams[i]);
    Result << "</dl>";
  }

  if (Parts.Params.size() != 0) {
    Result << "<dl>";
    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
      visit(Parts.Params[i]);
    Result << "</dl>";
  }

  if (Parts.Returns.size() != 0) {
    Result << "<div class=\"result-discussion\">";
    for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i)
      visit(Parts.Returns[i]);
    Result << "</div>";
  }

}

void CommentASTToHTMLConverter::visitNonStandaloneParagraphComment(
                                  const ParagraphComment *C) {
  if (!C)
    return;

  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
       I != E; ++I) {
    visit(*I);
  }
}

void CommentASTToHTMLConverter::appendToResultWithHTMLEscaping(StringRef S) {
  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
    const char C = *I;
    switch (C) {
    case '&':
      Result << "&amp;";
      break;
    case '<':
      Result << "&lt;";
      break;
    case '>':
      Result << "&gt;";
      break;
    case '"':
      Result << "&quot;";
      break;
    case '\'':
      Result << "&#39;";
      break;
    case '/':
      Result << "&#47;";
      break;
    default:
      Result << C;
      break;
    }
  }
}

namespace {
class CommentASTToXMLConverter :
    public ConstCommentVisitor<CommentASTToXMLConverter> {
public:
  /// \param Str accumulator for XML.
  CommentASTToXMLConverter(const FullComment *FC,
                           SmallVectorImpl<char> &Str,
                           const CommandTraits &Traits,
                           const SourceManager &SM) :
      FC(FC), Result(Str), Traits(Traits), SM(SM) { }

  // Inline content.
  void visitTextComment(const TextComment *C);
  void visitInlineCommandComment(const InlineCommandComment *C);
  void visitHTMLStartTagComment(const HTMLStartTagComment *C);
  void visitHTMLEndTagComment(const HTMLEndTagComment *C);

  // Block content.
  void visitParagraphComment(const ParagraphComment *C);

  void appendParagraphCommentWithKind(const ParagraphComment *C,
                                      StringRef Kind);

  void visitBlockCommandComment(const BlockCommandComment *C);
  void visitParamCommandComment(const ParamCommandComment *C);
  void visitTParamCommandComment(const TParamCommandComment *C);
  void visitVerbatimBlockComment(const VerbatimBlockComment *C);
  void visitVerbatimBlockLineComment(const VerbatimBlockLineComment *C);
  void visitVerbatimLineComment(const VerbatimLineComment *C);

  void visitFullComment(const FullComment *C);

  // Helpers.
  void appendToResultWithXMLEscaping(StringRef S);
  void appendToResultWithCDATAEscaping(StringRef S);

  void formatTextOfDeclaration(const DeclInfo *DI,
                               SmallString<128> &Declaration);

private:
  const FullComment *FC;

  /// Output stream for XML.
  llvm::raw_svector_ostream Result;

  const CommandTraits &Traits;
  const SourceManager &SM;
};

void getSourceTextOfDeclaration(const DeclInfo *ThisDecl,
                                SmallVectorImpl<char> &Str) {
  ASTContext &Context = ThisDecl->CurrentDecl->getASTContext();
  const LangOptions &LangOpts = Context.getLangOpts();
  llvm::raw_svector_ostream OS(Str);
  PrintingPolicy PPolicy(LangOpts);
  PPolicy.PolishForDeclaration = true;
  PPolicy.TerseOutput = true;
  PPolicy.ConstantsAsWritten = true;
  ThisDecl->CurrentDecl->print(OS, PPolicy,
                               /*Indentation*/0, /*PrintInstantiation*/false);
}

void CommentASTToXMLConverter::formatTextOfDeclaration(
    const DeclInfo *DI, SmallString<128> &Declaration) {
  // Formatting API expects null terminated input string.
  StringRef StringDecl(Declaration.c_str(), Declaration.size());

  // Formatter specific code.
  unsigned Offset = 0;
  unsigned Length = Declaration.size();

  format::FormatStyle Style = format::getLLVMStyle();
  Style.FixNamespaceComments = false;
  tooling::Replacements Replaces =
      reformat(Style, StringDecl, tooling::Range(Offset, Length), "xmldecl.xd");
  auto FormattedStringDecl = applyAllReplacements(StringDecl, Replaces);
  if (static_cast<bool>(FormattedStringDecl)) {
    Declaration = *FormattedStringDecl;
  }
}

} // end unnamed namespace

void CommentASTToXMLConverter::visitTextComment(const TextComment *C) {
  appendToResultWithXMLEscaping(C->getText());
}

void CommentASTToXMLConverter::visitInlineCommandComment(
    const InlineCommandComment *C) {
  // Nothing to render if no arguments supplied.
  if (C->getNumArgs() == 0)
    return;

  // Nothing to render if argument is empty.
  StringRef Arg0 = C->getArgText(0);
  if (Arg0.empty())
    return;

  switch (C->getRenderKind()) {
  case InlineCommandComment::RenderNormal:
    for (unsigned i = 0, e = C->getNumArgs(); i != e; ++i) {
      appendToResultWithXMLEscaping(C->getArgText(i));
      Result << " ";
    }
    return;
  case InlineCommandComment::RenderBold:
    assert(C->getNumArgs() == 1);
    Result << "<bold>";
    appendToResultWithXMLEscaping(Arg0);
    Result << "</bold>";
    return;
  case InlineCommandComment::RenderMonospaced:
    assert(C->getNumArgs() == 1);
    Result << "<monospaced>";
    appendToResultWithXMLEscaping(Arg0);
    Result << "</monospaced>";
    return;
  case InlineCommandComment::RenderEmphasized:
    assert(C->getNumArgs() == 1);
    Result << "<emphasized>";
    appendToResultWithXMLEscaping(Arg0);
    Result << "</emphasized>";
    return;
  case InlineCommandComment::RenderAnchor:
    assert(C->getNumArgs() == 1);
    Result << "<anchor id=\"" << Arg0 << "\"></anchor>";
    return;
  }
}

void CommentASTToXMLConverter::visitHTMLStartTagComment(
    const HTMLStartTagComment *C) {
  Result << "<rawHTML";
  if (C->isMalformed())
    Result << " isMalformed=\"1\"";
  Result << ">";
  {
    SmallString<32> Tag;
    {
      llvm::raw_svector_ostream TagOS(Tag);
      printHTMLStartTagComment(C, TagOS);
    }
    appendToResultWithCDATAEscaping(Tag);
  }
  Result << "</rawHTML>";
}

void
CommentASTToXMLConverter::visitHTMLEndTagComment(const HTMLEndTagComment *C) {
  Result << "<rawHTML";
  if (C->isMalformed())
    Result << " isMalformed=\"1\"";
  Result << ">&lt;/" << C->getTagName() << "&gt;</rawHTML>";
}

void
CommentASTToXMLConverter::visitParagraphComment(const ParagraphComment *C) {
  appendParagraphCommentWithKind(C, StringRef());
}

void CommentASTToXMLConverter::appendParagraphCommentWithKind(
                                  const ParagraphComment *C,
                                  StringRef ParagraphKind) {
  if (C->isWhitespace())
    return;

  if (ParagraphKind.empty())
    Result << "<Para>";
  else
    Result << "<Para kind=\"" << ParagraphKind << "\">";

  for (Comment::child_iterator I = C->child_begin(), E = C->child_end();
       I != E; ++I) {
    visit(*I);
  }
  Result << "</Para>";
}

void CommentASTToXMLConverter::visitBlockCommandComment(
    const BlockCommandComment *C) {
  StringRef ParagraphKind;

  switch (C->getCommandID()) {
  case CommandTraits::KCI_attention:
  case CommandTraits::KCI_author:
  case CommandTraits::KCI_authors:
  case CommandTraits::KCI_bug:
  case CommandTraits::KCI_copyright:
  case CommandTraits::KCI_date:
  case CommandTraits::KCI_invariant:
  case CommandTraits::KCI_note:
  case CommandTraits::KCI_post:
  case CommandTraits::KCI_pre:
  case CommandTraits::KCI_remark:
  case CommandTraits::KCI_remarks:
  case CommandTraits::KCI_sa:
  case CommandTraits::KCI_see:
  case CommandTraits::KCI_since:
  case CommandTraits::KCI_todo:
  case CommandTraits::KCI_version:
  case CommandTraits::KCI_warning:
    ParagraphKind = C->getCommandName(Traits);
    break;
  default:
    break;
  }

  appendParagraphCommentWithKind(C->getParagraph(), ParagraphKind);
}

void CommentASTToXMLConverter::visitParamCommandComment(
    const ParamCommandComment *C) {
  Result << "<Parameter><Name>";
  appendToResultWithXMLEscaping(C->isParamIndexValid()
                                    ? C->getParamName(FC)
                                    : C->getParamNameAsWritten());
  Result << "</Name>";

  if (C->isParamIndexValid()) {
    if (C->isVarArgParam())
      Result << "<IsVarArg />";
    else
      Result << "<Index>" << C->getParamIndex() << "</Index>";
  }

  Result << "<Direction isExplicit=\"" << C->isDirectionExplicit() << "\">";
  switch (C->getDirection()) {
  case ParamCommandComment::In:
    Result << "in";
    break;
  case ParamCommandComment::Out:
    Result << "out";
    break;
  case ParamCommandComment::InOut:
    Result << "in,out";
    break;
  }
  Result << "</Direction><Discussion>";
  visit(C->getParagraph());
  Result << "</Discussion></Parameter>";
}

void CommentASTToXMLConverter::visitTParamCommandComment(
                                  const TParamCommandComment *C) {
  Result << "<Parameter><Name>";
  appendToResultWithXMLEscaping(C->isPositionValid() ? C->getParamName(FC)
                                : C->getParamNameAsWritten());
  Result << "</Name>";

  if (C->isPositionValid() && C->getDepth() == 1) {
    Result << "<Index>" << C->getIndex(0) << "</Index>";
  }

  Result << "<Discussion>";
  visit(C->getParagraph());
  Result << "</Discussion></Parameter>";
}

void CommentASTToXMLConverter::visitVerbatimBlockComment(
                                  const VerbatimBlockComment *C) {
  unsigned NumLines = C->getNumLines();
  if (NumLines == 0)
    return;

  switch (C->getCommandID()) {
  case CommandTraits::KCI_code:
    Result << "<Verbatim xml:space=\"preserve\" kind=\"code\">";
    break;
  default:
    Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
    break;
  }
  for (unsigned i = 0; i != NumLines; ++i) {
    appendToResultWithXMLEscaping(C->getText(i));
    if (i + 1 != NumLines)
      Result << '\n';
  }
  Result << "</Verbatim>";
}

void CommentASTToXMLConverter::visitVerbatimBlockLineComment(
                                  const VerbatimBlockLineComment *C) {
  llvm_unreachable("should not see this AST node");
}

void CommentASTToXMLConverter::visitVerbatimLineComment(
                                  const VerbatimLineComment *C) {
  Result << "<Verbatim xml:space=\"preserve\" kind=\"verbatim\">";
  appendToResultWithXMLEscaping(C->getText());
  Result << "</Verbatim>";
}

void CommentASTToXMLConverter::visitFullComment(const FullComment *C) {
  FullCommentParts Parts(C, Traits);

  const DeclInfo *DI = C->getDeclInfo();
  StringRef RootEndTag;
  if (DI) {
    switch (DI->getKind()) {
    case DeclInfo::OtherKind:
      RootEndTag = "</Other>";
      Result << "<Other";
      break;
    case DeclInfo::FunctionKind:
      RootEndTag = "</Function>";
      Result << "<Function";
      switch (DI->TemplateKind) {
      case DeclInfo::NotTemplate:
        break;
      case DeclInfo::Template:
        Result << " templateKind=\"template\"";
        break;
      case DeclInfo::TemplateSpecialization:
        Result << " templateKind=\"specialization\"";
        break;
      case DeclInfo::TemplatePartialSpecialization:
        llvm_unreachable("partial specializations of functions "
                         "are not allowed in C++");
      }
      if (DI->IsInstanceMethod)
        Result << " isInstanceMethod=\"1\"";
      if (DI->IsClassMethod)
        Result << " isClassMethod=\"1\"";
      break;
    case DeclInfo::ClassKind:
      RootEndTag = "</Class>";
      Result << "<Class";
      switch (DI->TemplateKind) {
      case DeclInfo::NotTemplate:
        break;
      case DeclInfo::Template:
        Result << " templateKind=\"template\"";
        break;
      case DeclInfo::TemplateSpecialization:
        Result << " templateKind=\"specialization\"";
        break;
      case DeclInfo::TemplatePartialSpecialization:
        Result << " templateKind=\"partialSpecialization\"";
        break;
      }
      break;
    case DeclInfo::VariableKind:
      RootEndTag = "</Variable>";
      Result << "<Variable";
      break;
    case DeclInfo::NamespaceKind:
      RootEndTag = "</Namespace>";
      Result << "<Namespace";
      break;
    case DeclInfo::TypedefKind:
      RootEndTag = "</Typedef>";
      Result << "<Typedef";
      break;
    case DeclInfo::EnumKind:
      RootEndTag = "</Enum>";
      Result << "<Enum";
      break;
    }

    {
      // Print line and column number.
      SourceLocation Loc = DI->CurrentDecl->getLocation();
      std::pair<FileID, unsigned> LocInfo = SM.getDecomposedLoc(Loc);
      FileID FID = LocInfo.first;
      unsigned FileOffset = LocInfo.second;

      if (FID.isValid()) {
        if (const FileEntry *FE = SM.getFileEntryForID(FID)) {
          Result << " file=\"";
          appendToResultWithXMLEscaping(FE->getName());
          Result << "\"";
        }
        Result << " line=\"" << SM.getLineNumber(FID, FileOffset)
               << "\" column=\"" << SM.getColumnNumber(FID, FileOffset)
               << "\"";
      }
    }

    // Finish the root tag.
    Result << ">";

    bool FoundName = false;
    if (const NamedDecl *ND = dyn_cast<NamedDecl>(DI->CommentDecl)) {
      if (DeclarationName DeclName = ND->getDeclName()) {
        Result << "<Name>";
        std::string Name = DeclName.getAsString();
        appendToResultWithXMLEscaping(Name);
        FoundName = true;
        Result << "</Name>";
      }
    }
    if (!FoundName)
      Result << "<Name>&lt;anonymous&gt;</Name>";

    {
      // Print USR.
      SmallString<128> USR;
      generateUSRForDecl(DI->CommentDecl, USR);
      if (!USR.empty()) {
        Result << "<USR>";
        appendToResultWithXMLEscaping(USR);
        Result << "</USR>";
      }
    }
  } else {
    // No DeclInfo -- just emit some root tag and name tag.
    RootEndTag = "</Other>";
    Result << "<Other><Name>unknown</Name>";
  }

  if (Parts.Headerfile) {
    Result << "<Headerfile>";
    visit(Parts.Headerfile);
    Result << "</Headerfile>";
  }

  {
    // Pretty-print the declaration.
    Result << "<Declaration>";
    SmallString<128> Declaration;
    getSourceTextOfDeclaration(DI, Declaration);
    formatTextOfDeclaration(DI, Declaration);
    appendToResultWithXMLEscaping(Declaration);
    Result << "</Declaration>";
  }

  bool FirstParagraphIsBrief = false;
  if (Parts.Brief) {
    Result << "<Abstract>";
    visit(Parts.Brief);
    Result << "</Abstract>";
  } else if (Parts.FirstParagraph) {
    Result << "<Abstract>";
    visit(Parts.FirstParagraph);
    Result << "</Abstract>";
    FirstParagraphIsBrief = true;
  }

  if (Parts.TParams.size() != 0) {
    Result << "<TemplateParameters>";
    for (unsigned i = 0, e = Parts.TParams.size(); i != e; ++i)
      visit(Parts.TParams[i]);
    Result << "</TemplateParameters>";
  }

  if (Parts.Params.size() != 0) {
    Result << "<Parameters>";
    for (unsigned i = 0, e = Parts.Params.size(); i != e; ++i)
      visit(Parts.Params[i]);
    Result << "</Parameters>";
  }

  if (Parts.Exceptions.size() != 0) {
    Result << "<Exceptions>";
    for (unsigned i = 0, e = Parts.Exceptions.size(); i != e; ++i)
      visit(Parts.Exceptions[i]);
    Result << "</Exceptions>";
  }

  if (Parts.Returns.size() != 0) {
    Result << "<ResultDiscussion>";
    for (unsigned i = 0, e = Parts.Returns.size(); i != e; ++i)
      visit(Parts.Returns[i]);
    Result << "</ResultDiscussion>";
  }

  if (DI->CommentDecl->hasAttrs()) {
    const AttrVec &Attrs = DI->CommentDecl->getAttrs();
    for (unsigned i = 0, e = Attrs.size(); i != e; i++) {
      const AvailabilityAttr *AA = dyn_cast<AvailabilityAttr>(Attrs[i]);
      if (!AA) {
        if (const DeprecatedAttr *DA = dyn_cast<DeprecatedAttr>(Attrs[i])) {
          if (DA->getMessage().empty())
            Result << "<Deprecated/>";
          else {
            Result << "<Deprecated>";
            appendToResultWithXMLEscaping(DA->getMessage());
            Result << "</Deprecated>";
          }
        }
        else if (const UnavailableAttr *UA = dyn_cast<UnavailableAttr>(Attrs[i])) {
          if (UA->getMessage().empty())
            Result << "<Unavailable/>";
          else {
            Result << "<Unavailable>";
            appendToResultWithXMLEscaping(UA->getMessage());
            Result << "</Unavailable>";
          }
        }
        continue;
      }

      // 'availability' attribute.
      Result << "<Availability";
      StringRef Distribution;
      if (AA->getPlatform()) {
        Distribution = AvailabilityAttr::getPrettyPlatformName(
                                        AA->getPlatform()->getName());
        if (Distribution.empty())
          Distribution = AA->getPlatform()->getName();
      }
      Result << " distribution=\"" << Distribution << "\">";
      VersionTuple IntroducedInVersion = AA->getIntroduced();
      if (!IntroducedInVersion.empty()) {
        Result << "<IntroducedInVersion>"
               << IntroducedInVersion.getAsString()
               << "</IntroducedInVersion>";
      }
      VersionTuple DeprecatedInVersion = AA->getDeprecated();
      if (!DeprecatedInVersion.empty()) {
        Result << "<DeprecatedInVersion>"
               << DeprecatedInVersion.getAsString()
               << "</DeprecatedInVersion>";
      }
      VersionTuple RemovedAfterVersion = AA->getObsoleted();
      if (!RemovedAfterVersion.empty()) {
        Result << "<RemovedAfterVersion>"
               << RemovedAfterVersion.getAsString()
               << "</RemovedAfterVersion>";
      }
      StringRef DeprecationSummary = AA->getMessage();
      if (!DeprecationSummary.empty()) {
        Result << "<DeprecationSummary>";
        appendToResultWithXMLEscaping(DeprecationSummary);
        Result << "</DeprecationSummary>";
      }
      if (AA->getUnavailable())
        Result << "<Unavailable/>";
      Result << "</Availability>";
    }
  }

  {
    bool StartTagEmitted = false;
    for (unsigned i = 0, e = Parts.MiscBlocks.size(); i != e; ++i) {
      const Comment *C = Parts.MiscBlocks[i];
      if (FirstParagraphIsBrief && C == Parts.FirstParagraph)
        continue;
      if (!StartTagEmitted) {
        Result << "<Discussion>";
        StartTagEmitted = true;
      }
      visit(C);
    }
    if (StartTagEmitted)
      Result << "</Discussion>";
  }

  Result << RootEndTag;
}

void CommentASTToXMLConverter::appendToResultWithXMLEscaping(StringRef S) {
  for (StringRef::iterator I = S.begin(), E = S.end(); I != E; ++I) {
    const char C = *I;
    switch (C) {
    case '&':
      Result << "&amp;";
      break;
    case '<':
      Result << "&lt;";
      break;
    case '>':
      Result << "&gt;";
      break;
    case '"':
      Result << "&quot;";
      break;
    case '\'':
      Result << "&apos;";
      break;
    default:
      Result << C;
      break;
    }
  }
}

void CommentASTToXMLConverter::appendToResultWithCDATAEscaping(StringRef S) {
  if (S.empty())
    return;

  Result << "<![CDATA[";
  while (!S.empty()) {
    size_t Pos = S.find("]]>");
    if (Pos == 0) {
      Result << "]]]]><![CDATA[>";
      S = S.drop_front(3);
      continue;
    }
    if (Pos == StringRef::npos)
      Pos = S.size();

    Result << S.substr(0, Pos);

    S = S.drop_front(Pos);
  }
  Result << "]]>";
}

CommentToXMLConverter::CommentToXMLConverter() {}
CommentToXMLConverter::~CommentToXMLConverter() {}

void CommentToXMLConverter::convertCommentToHTML(const FullComment *FC,
                                                 SmallVectorImpl<char> &HTML,
                                                 const ASTContext &Context) {
  CommentASTToHTMLConverter Converter(FC, HTML,
                                      Context.getCommentCommandTraits());
  Converter.visit(FC);
}

void CommentToXMLConverter::convertHTMLTagNodeToText(
    const comments::HTMLTagComment *HTC, SmallVectorImpl<char> &Text,
    const ASTContext &Context) {
  CommentASTToHTMLConverter Converter(nullptr, Text,
                                      Context.getCommentCommandTraits());
  Converter.visit(HTC);
}

void CommentToXMLConverter::convertCommentToXML(const FullComment *FC,
                                                SmallVectorImpl<char> &XML,
                                                const ASTContext &Context) {
  CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(),
                                     Context.getSourceManager());
  Converter.visit(FC);
}
