//===--- CommentToXML.cpp - Convert comments to XML representation --------===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//

#include "clang/Index/CommentToXML.h"
#include "SimpleFormatContext.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.
  std::stable_sort(Params.begin(), Params.end(),
                   ParamCommandCommentCompareIndex());

  std::stable_sort(TParams.begin(), TParams.end(),
                   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;
  }
}

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,
                           SimpleFormatContext &SFC,
                           unsigned FUID) :
      FC(FC), Result(Str), Traits(Traits), SM(SM),
      FormatRewriterContext(SFC),
      FormatInMemoryUniqueId(FUID) { }

  // 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;
  SimpleFormatContext &FormatRewriterContext;
  unsigned FormatInMemoryUniqueId;
};

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;
  ThisDecl->CurrentDecl->print(OS, PPolicy,
                               /*Indentation*/0, /*PrintInstantiation*/false);
}

void CommentASTToXMLConverter::formatTextOfDeclaration(
    const DeclInfo *DI, SmallString<128> &Declaration) {
  // FIXME. formatting API expects null terminated input string.
  // There might be more efficient way of doing this.
  std::string StringDecl = Declaration.str();

  // Formatter specific code.
  // Form a unique in memory buffer name.
  SmallString<128> filename;
  filename += "xmldecl";
  filename += llvm::utostr(FormatInMemoryUniqueId);
  filename += ".xd";
  FileID ID = FormatRewriterContext.createInMemoryFile(filename, StringDecl);
  SourceLocation Start = FormatRewriterContext.Sources.getLocForStartOfFile(ID)
      .getLocWithOffset(0);
  unsigned Length = Declaration.size();

  tooling::Replacements Replace = reformat(
      format::getLLVMStyle(), FormatRewriterContext.Sources, ID,
      CharSourceRange::getCharRange(Start, Start.getLocWithOffset(Length)));
  applyAllReplacements(Replace, FormatRewriterContext.Rewrite);
  Declaration = FormatRewriterContext.getRewrittenText(ID);
}

} // 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;
  }
}

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);
  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() : FormatInMemoryUniqueId(0) {}
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) {
  if (!FormatContext || (FormatInMemoryUniqueId % 1000) == 0) {
    // Create a new format context, or re-create it after some number of
    // iterations, so the buffers don't grow too large.
    FormatContext.reset(new SimpleFormatContext(Context.getLangOpts()));
  }

  CommentASTToXMLConverter Converter(FC, XML, Context.getCommentCommandTraits(),
                                     Context.getSourceManager(), *FormatContext,
                                     FormatInMemoryUniqueId++);
  Converter.visit(FC);
}

