//===--- 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 "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) :
      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;
  }
}

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() {}
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);
}
