/*
 * Copyright 2017 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkOSFile.h"
#include "SkOSPath.h"

#include "bmhParser.h"
#include "includeParser.h"

const IncludeKey kKeyWords[] = {
    { "",           KeyWord::kNone,         KeyProperty::kNone           },
    { "SK_API",     KeyWord::kSK_API,       KeyProperty::kModifier       },
    { "SK_BEGIN_REQUIRE_DENSE", KeyWord::kSK_BEGIN_REQUIRE_DENSE, KeyProperty::kModifier },
    { "alignas",    KeyWord::kAlignAs,      KeyProperty::kModifier       },
    { "bool",       KeyWord::kBool,         KeyProperty::kNumber         },
    { "char",       KeyWord::kChar,         KeyProperty::kNumber         },
    { "class",      KeyWord::kClass,        KeyProperty::kObject         },
    { "const",      KeyWord::kConst,        KeyProperty::kModifier       },
    { "constexpr",  KeyWord::kConstExpr,    KeyProperty::kModifier       },
    { "define",     KeyWord::kDefine,       KeyProperty::kPreprocessor   },
    { "double",     KeyWord::kDouble,       KeyProperty::kNumber         },
    { "elif",       KeyWord::kElif,         KeyProperty::kPreprocessor   },
    { "else",       KeyWord::kElse,         KeyProperty::kPreprocessor   },
    { "endif",      KeyWord::kEndif,        KeyProperty::kPreprocessor   },
    { "enum",       KeyWord::kEnum,         KeyProperty::kObject         },
    { "error",      KeyWord::kError,        KeyProperty::kPreprocessor   },
    { "float",      KeyWord::kFloat,        KeyProperty::kNumber         },
    { "friend",     KeyWord::kFriend,       KeyProperty::kModifier       },
    { "if",         KeyWord::kIf,           KeyProperty::kPreprocessor   },
    { "ifdef",      KeyWord::kIfdef,        KeyProperty::kPreprocessor   },
    { "ifndef",     KeyWord::kIfndef,       KeyProperty::kPreprocessor   },
    { "include",    KeyWord::kInclude,      KeyProperty::kPreprocessor   },
    { "inline",     KeyWord::kInline,       KeyProperty::kModifier       },
    { "int",        KeyWord::kInt,          KeyProperty::kNumber         },
    { "operator",   KeyWord::kOperator,     KeyProperty::kFunction       },
    { "private",    KeyWord::kPrivate,      KeyProperty::kClassSection   },
    { "protected",  KeyWord::kProtected,    KeyProperty::kClassSection   },
    { "public",     KeyWord::kPublic,       KeyProperty::kClassSection   },
    { "signed",     KeyWord::kSigned,       KeyProperty::kNumber         },
    { "size_t",     KeyWord::kSize_t,       KeyProperty::kNumber         },
    { "static",     KeyWord::kStatic,       KeyProperty::kModifier       },
    { "struct",     KeyWord::kStruct,       KeyProperty::kObject         },
    { "template",   KeyWord::kTemplate,     KeyProperty::kObject         },
    { "typedef",    KeyWord::kTypedef,      KeyProperty::kObject         },
    { "typename",   KeyWord::kTypename,     KeyProperty::kObject         },
    { "uint16_t",   KeyWord::kUint16_t,     KeyProperty::kNumber         },
    { "uint32_t",   KeyWord::kUint32_t,     KeyProperty::kNumber         },
    { "uint64_t",   KeyWord::kUint64_t,     KeyProperty::kNumber         },
    { "uint8_t",    KeyWord::kUint8_t,      KeyProperty::kNumber         },
    { "uintptr_t",  KeyWord::kUintPtr_t,    KeyProperty::kNumber         },
    { "union",      KeyWord::kUnion,        KeyProperty::kObject         },
    { "unsigned",   KeyWord::kUnsigned,     KeyProperty::kNumber         },
    { "using",      KeyWord::kUsing,        KeyProperty::kObject         },
    { "void",       KeyWord::kVoid,         KeyProperty::kNumber         },
};

const size_t kKeyWordCount = SK_ARRAY_COUNT(kKeyWords);

KeyWord IncludeParser::FindKey(const char* start, const char* end) {
    int ch = 0;
    for (size_t index = 0; index < kKeyWordCount; ) {
        if (start[ch] > kKeyWords[index].fName[ch]) {
            ++index;
            if (ch > 0 && (index == kKeyWordCount ||
                    kKeyWords[index - 1].fName[ch - 1] < kKeyWords[index].fName[ch - 1])) {
                return KeyWord::kNone;
            }
            continue;
        }
        if (start[ch] < kKeyWords[index].fName[ch]) {
            return KeyWord::kNone;
        }
        ++ch;
        if (start + ch >= end) {
            if (end - start < (int) strlen(kKeyWords[index].fName)) {
                return KeyWord::kNone;
            }
            return kKeyWords[index].fKeyWord;
        }
    }
    return KeyWord::kNone;
}

void IncludeParser::ValidateKeyWords() {
    for (size_t index = 1; index < kKeyWordCount; ++index) {
        SkASSERT((int) kKeyWords[index - 1].fKeyWord + 1
                == (int) kKeyWords[index].fKeyWord);
        SkASSERT(0 > strcmp(kKeyWords[index - 1].fName, kKeyWords[index].fName));
    }
}

void IncludeParser::addKeyword(KeyWord keyWord) {
    fParent->fTokens.emplace_back(keyWord, fIncludeWord, fChar, fLineCount, fParent, '\0');
    fIncludeWord = nullptr;
    if (KeyProperty::kObject == kKeyWords[(int) keyWord].fProperty) {
        Definition* def = &fParent->fTokens.back();
        this->addDefinition(def);
        if (KeyWord::kEnum == fParent->fKeyWord) {
            fInEnum = true;
        }
    }
}

static bool looks_like_method(const TextParser& tp) {
    TextParser t(tp.fFileName, tp.fLine, tp.fChar, tp.fLineCount);
    t.skipSpace();
    if (!t.skipExact("struct") && !t.skipExact("class") && !t.skipExact("enum class")
            && !t.skipExact("enum")) {
        return true;
    }
    t.skipSpace();
    if (t.skipExact("SK_API")) {
        t.skipSpace();
    }
    if (!isupper(t.peek())) {
        return true;
    }
    return nullptr != t.strnchr('(', t.fEnd);
}

static bool looks_like_forward_declaration(const TextParser& tp) {
    TextParser t(tp.fFileName, tp.fChar, tp.lineEnd(), tp.fLineCount);
    t.skipSpace();
    if (!t.skipExact("struct") && !t.skipExact("class") && !t.skipExact("enum class")
            && !t.skipExact("enum")) {
        return false;
    }
    t.skipSpace();
    if (t.skipExact("SK_API")) {
        t.skipSpace();
    }
    if (!isupper(t.peek())) {
        return false;
    }
    t.skipToNonAlphaNum();
    if (t.eof() || ';' != t.next()) {
        return false;
    }
    if (t.eof() || '\n' != t.next()) {
        return false;
    }
    return t.eof();
}

static bool looks_like_constructor(const TextParser& tp) {
    TextParser t(tp.fFileName, tp.fLine, tp.lineEnd(), tp.fLineCount);
    t.skipSpace();
    if (!isupper(t.peek())) {
        if (':' == t.next() && ' ' >= t.peek()) {
            return true;
        }
        return false;
    }
    t.skipToNonAlphaNum();
    if ('(' != t.peek()) {
        return false;
    }
    if (!t.skipToEndBracket(')')) {
        return false;
    }
    SkAssertResult(')' == t.next());
    t.skipSpace();
    return tp.fChar == t.fChar;
}

static bool looks_like_class_decl(const TextParser& tp) {
    TextParser t(tp.fFileName, tp.fLine, tp.fChar, tp.fLineCount);
    t.skipSpace();
    if (!t.skipExact("class")) {
        return false;
    }
    t.skipSpace();
    if (t.skipExact("SK_API")) {
        t.skipSpace();
    }
    if (!isupper(t.peek())) {
        return false;
    }
    t.skipToNonAlphaNum();
    return !t.skipToEndBracket('(');
}

static bool looks_like_const(const TextParser& tp) {
    TextParser t(tp.fFileName, tp.fChar, tp.lineEnd(), tp.fLineCount);
    if (!t.startsWith("static constexpr ")) {
        return false;
    }
    if (t.skipToEndBracket(" k")) {
        SkAssertResult(t.skipExact(" k"));
    } else if (t.skipToEndBracket(" SK_")) {
        SkAssertResult(t.skipExact(" SK_"));
    } else {
        return false;
    }
    if (!isupper(t.peek())) {
        return false;
    }
    return t.skipToEndBracket(" = ");
}

static bool looks_like_member(const TextParser& tp) {
    TextParser t(tp.fFileName, tp.fChar, tp.lineEnd(), tp.fLineCount);
    const char* end = t.anyOf("(;");
    if (!end || '(' == *end) {
        return false;
    }
    bool foundMember = false;
    do {
        const char* next = t.anyOf(" ;");
        if (';' == *next) {
            break;
        }
        t.skipTo(next);
        t.skipSpace();
        foundMember = 'f' == t.fChar[0] && isupper(t.fChar[1]);
    } while (true);
    return foundMember;
}

static void skip_constructor_initializers(TextParser& t) {
    SkAssertResult(':' == t.next());
    do {
        t.skipWhiteSpace();
        t.skipToNonAlphaNum();
        t.skipWhiteSpace();
        if ('{' == t.peek()) {
            t.skipToBalancedEndBracket('{', '}');
        }
        do {
            const char* limiter = t.anyOf("(,{");
            t.skipTo(limiter);
            if ('(' != t.peek()) {
                break;
            }
            t.skipToBalancedEndBracket('(', ')');
        } while (true);
        if ('{' == t.peek()) {
            return;
        }
        SkAssertResult(',' == t.next());
    } while (true);
}

static const char kInline[] = "inline ";
static const char kSK_API[] = "SK_API ";
static const char kSK_WARN_UNUSED_RESULT[] = "SK_WARN_UNUSED_RESULT ";

bool IncludeParser::advanceInclude(TextParser& i) {
    if (!i.skipWhiteSpace(&fCheck.fIndent, &fCheck.fWriteReturn)) {
        return false;
    }
    if (fCheck.fPrivateBrace) {
        if (i.startsWith("};")) {
            if (fCheck.fPrivateBrace == fCheck.fBraceCount) {
                fCheck.fPrivateBrace = 0;
                fCheck.fDoubleReturn = true;
            } else {
                i.skipExact("};");
                fCheck.fBraceCount -= 1;
            }
            return false;
        }
        if (i.startsWith("public:")) {
            if (fCheck.fBraceCount <= fCheck.fPrivateBrace) {
                fCheck.fPrivateBrace = 0;
                if (fCheck.fPrivateProtected) {
                    i.skipExact("public:");
                }
            } else {
                i.skipExact("public:");
            }
        } else {
            fCheck.fBraceCount += i.skipToLineBalance('{', '}');
        }
        return false;
    } else if (i.startsWith("};")) {
        fCheck.fDoubleReturn = 2;
    }
    if (i.skipExact(kInline)) {
        fCheck.fSkipInline = true;
        return false;
    }
    if (i.skipExact(kSK_API)) {
        fCheck.fSkipAPI = true;
        return false;
    }
    if (i.skipExact(kSK_WARN_UNUSED_RESULT)) {
        fCheck.fSkipWarnUnused = true;
        return false;
    }
    if (i.skipExact("SK_ATTR_DEPRECATED")) {
        i.skipToLineStart(&fCheck.fIndent, &fCheck.fWriteReturn);
        return false;
    }
    if (i.skipExact("SkDEBUGCODE")) {
        i.skipWhiteSpace();
        if ('(' != i.peek()) {
            i.reportError("expected open paren");
        }
        TextParserSave save(&i);
        SkAssertResult(i.skipToBalancedEndBracket('(', ')'));
        fCheck.fInDebugCode = i.fChar - 1;
        save.restore();
        SkAssertResult('(' == i.next());
    }
    if ('{' == i.peek()) {
        if (looks_like_method(i)) {
            fCheck.fState = CheckCode::State::kMethod;
            if (!i.skipToBalancedEndBracket('{', '}')) {
                i.reportError("unbalanced open brace");
            }
            i.skipToLineStart(&fCheck.fIndent, &fCheck.fWriteReturn);
            return false;
        } else if (looks_like_class_decl(i)) {
            fCheck.fState = CheckCode::State::kClassDeclaration;
            fCheck.fPrivateBrace = fCheck.fBraceCount + 1;
            fCheck.fPrivateProtected = false;
        }
    }
    if (':' == i.peek() && looks_like_constructor(i)) {
        fCheck.fState = CheckCode::State::kConstructor;
        skip_constructor_initializers(i);
        return false;
    }
    if ('#' == i.peek()) {
        i.skipToLineStart(&fCheck.fIndent, &fCheck.fWriteReturn);
        return false;
    }
    if (i.startsWith("//")) {
        i.skipToLineStart(&fCheck.fIndent, &fCheck.fWriteReturn);
        return false;
    }
    if (i.startsWith("/*")) {
        i.skipToEndBracket("*/");
        i.skipToLineStart(&fCheck.fIndent, &fCheck.fWriteReturn);
        return false;
    }
    if (looks_like_forward_declaration(i)) {
        fCheck.fState = CheckCode::State::kForwardDeclaration;
        i.skipToLineStart(&fCheck.fIndent, &fCheck.fWriteReturn);
        return false;
    }
    if (i.skipExact("private:") || i.skipExact("protected:")) {
        if (!fCheck.fBraceCount) {
            i.reportError("expect private in brace");
        }
        fCheck.fPrivateBrace = fCheck.fBraceCount;
        fCheck.fPrivateProtected = true;
        return false;
    }
    const char* funcEnd = i.anyOf("(\n");
    if (funcEnd && '(' == funcEnd[0] && '_' == *i.anyOf("_(")
            && (i.contains("internal_", funcEnd, nullptr)
            || i.contains("private_", funcEnd, nullptr)
            || i.contains("legacy_", funcEnd, nullptr)
            || i.contains("temporary_", funcEnd, nullptr))) {
        i.skipTo(funcEnd);
        if (!i.skipToBalancedEndBracket('(', ')')) {
            i.reportError("unbalanced open parent");
        }
        i.skipSpace();
        i.skipExact("const ");
        i.skipSpace();
        if (';' == i.peek()) {
            i.next();
        }
        fCheck.fState = CheckCode::State::kNone;
        return false;
    }
    return true;
}

void IncludeParser::codeBlockAppend(string& result, string s) const {
    for (char c : s) {
        this->codeBlockAppend(result, c);
    }
}

void IncludeParser::codeBlockAppend(string& result, char ch) const {
    if (Elided::kYes == fElided && fCheck.fBraceCount) {
        return;
    }
    this->stringAppend(result, ch);
}

void IncludeParser::codeBlockSpaces(string& result, int indent) const {
    if (!indent) {
        return;
    }
    if (Elided::kYes == fElided && fCheck.fBraceCount) {
        return;
    }
    SkASSERT(indent > 0);
    if (fDebugWriteCodeBlock) {
        SkDebugf("%*c", indent, ' ');
    }
    result.append(indent, ' ');
}

string IncludeParser::writeCodeBlock(const Definition& iDef) {
    if (MarkType::kComment == iDef.fMarkType) {
        return "";
    }
    if (iDef.fUndocumented) {
        return "";
    }
    TextParser i(&iDef);
    (void) i.skipExact("SkDEBUGCODE(");
    if (MarkType::kConst == iDef.fMarkType && !i.fEnd) {
        // TODO: end should have been set earlier
        auto iter = iDef.fParent->fTokens.begin();
        std::advance(iter, iDef.fParentIndex + 1);
        SkASSERT(iter != iDef.fParent->fTokens.end());
        i.fEnd = iter->fContentStart;
    }
    const char* loc;
    if (MarkType::kMember == iDef.fMarkType) {
        const char* parentEnd = iDef.fParent->fContentEnd;
        TextParser newEnd(&iDef);
        newEnd.fEnd = parentEnd;
        const char* memberEnd = newEnd.anyOf(",};");
        if (memberEnd && (';' == memberEnd[0] || ',' == memberEnd[0])) {
            i.fEnd = memberEnd + 1;
        }
    }
    if (i.contains("//", i.fEnd, &loc)) {
        i.fEnd = loc;
    }
    if (i.contains("/*", i.fEnd, &loc)) {
        i.fEnd = loc;
    }
    if (i.contains("{", i.fEnd, &loc)) {
        i.fEnd = loc + 1;
        while (i.fEnd < iDef.fContentEnd && ' ' >= i.fEnd[0]) {
            ++i.fEnd;
        }
    }
    while (i.fEnd > i.fStart && ' ' == i.fEnd[-1]) {
        --i.fEnd;
    }
    const char* before = iDef.fContentStart;
    while (' ' == *--before)
        ;
    int startIndent = iDef.fContentStart - before - 1;
    bool saveDebugWriteBlock = fDebugWriteCodeBlock;
    fDebugWriteCodeBlock = false;
    string result = writeCodeBlock(i, iDef.fMarkType, startIndent);
    fDebugWriteCodeBlock = saveDebugWriteBlock;
    if (!result.empty()) {
        if (MarkType::kNone != fPreviousMarkType && iDef.fMarkType != fPreviousMarkType
                && ((MarkType::kEnum != fPreviousMarkType
                && MarkType::kEnumClass != fPreviousMarkType)
                || MarkType::kMember != iDef.fMarkType)
                && (MarkType::kMember != fPreviousMarkType
                || iDef.fParent == fPreviousDef->fParent)) {
            result = "\n" + result;
        }
        if (fDebugWriteCodeBlock) {
            SkDebugf("%s", result.c_str());
        }
        fPreviousDef = &iDef;
        fPreviousMarkType = iDef.fMarkType;
    }
    for (auto& token : iDef.fTokens) {
        result += this->writeCodeBlock(token);
    }
    if (MarkType::kEnum == iDef.fMarkType || MarkType::kEnumClass == iDef.fMarkType
            || MarkType::kStruct == iDef.fMarkType || MarkType::kClass == iDef.fMarkType) {
        this->codeBlockSpaces(result, startIndent);
        this->codeBlockAppend(result, "};\n\n");
    }
    return result;
}

string IncludeParser::writeCodeBlock(TextParser& i, MarkType markType, int startIndent) {
    string result;
    char last;
    int lastIndent = 0;
    bool lastDoubleMeUp = false;
    fCheck.reset();
    if (MarkType::kDefine == markType) {
        result = "#define ";
    } else {
        this->codeBlockSpaces(result, startIndent);
    }
    do {
        if (!this->advanceInclude(i)) {
            continue;
        }
        do {
            last = i.peek();
            SkASSERT(' ' < last);
            if (fCheck.fInDebugCode == i.fChar) {
                fCheck.fInDebugCode = nullptr;
                i.next();   // skip close paren
                break;
            }
            if (CheckCode::State::kMethod == fCheck.fState) {
                this->codeBlockAppend(result, ';');
                fCheck.fState = CheckCode::State::kNone;
            }
            if (fCheck.fWriteReturn) {
                this->codeBlockAppend(result, '\n');
                bool doubleMeUp = i.startsWith("typedef ") || looks_like_const(i)
                        || (!strncmp("struct ", i.fStart, 7) && looks_like_member(i));
                if ((!--fCheck.fDoubleReturn && !i.startsWith("};")) || i.startsWith("enum ")
                        || i.startsWith("typedef ") || doubleMeUp || fCheck.fTypedefReturn
                        || (fCheck.fIndent && (i.startsWith("class ") || i.startsWith("struct ")))) {
                    if (lastIndent > 0 && (!doubleMeUp || !lastDoubleMeUp)) {
                        this->codeBlockAppend(result, '\n');
                    }
                    fCheck.fTypedefReturn = false;
                    lastDoubleMeUp = doubleMeUp;
                }
                if (doubleMeUp) {
                    fCheck.fTypedefReturn = true;
                }
                lastIndent = fCheck.fIndent;
            }
            if (fCheck.fIndent) {
                size_t indent = fCheck.fIndent;
                if (fCheck.fSkipInline && indent > sizeof(kInline)) {
                    indent -= sizeof(kInline) - 1;
                }
                if (fCheck.fSkipAPI && indent > sizeof(kSK_API)) {
                    indent -= sizeof(kSK_API) - 1;
                }
                if (fCheck.fSkipWarnUnused && indent > sizeof(kSK_WARN_UNUSED_RESULT)) {
                    indent -= sizeof(kSK_WARN_UNUSED_RESULT) - 1;
                }

                this->codeBlockSpaces(result, indent);
            }
            this->codeBlockAppend(result, last);
            fCheck.fWriteReturn = false;
            fCheck.fIndent = 0;
            fCheck.fBraceCount += '{' == last;
            fCheck.fBraceCount -= '}' == last;
            if (';' == last) {
                fCheck.fSkipInline = false;
                fCheck.fSkipAPI = false;
                fCheck.fSkipWarnUnused = false;
            }
            if (fCheck.fBraceCount < 0) {
                i.reportError("unbalanced close brace");
                return result;
            }
            i.next();
        } while (!i.eof() && ' ' < i.peek() && !i.startsWith("//"));
    } while (!i.eof());
    if (CheckCode::State::kMethod == fCheck.fState) {
        this->codeBlockAppend(result, ';');
    }
    bool elided = Elided::kYes == fElided;
    bool elidedTemplate = elided && !strncmp(i.fStart, "template ", 9);
    bool elidedTClass = elidedTemplate && MarkType::kClass == markType;
    bool statementEnd = !result.empty() && (MarkType::kMethod == markType
            || MarkType::kTypedef == markType || '}' == result.back());
    bool semiEnd = !result.empty() && (',' == result.back() || ';' == result.back());
    if (fCheck.fWriteReturn || elidedTClass) {
        this->codeBlockAppend(result, '\n');
    }
    if (elided && ((MarkType::kFunction != markType && lastIndent > startIndent) || elidedTClass)) {
        this->codeBlockAppend(result, '}');
        statementEnd = true;
    }
    if (elided || statementEnd) {
        this->codeBlockAppend(result, ";\n");
    } else if (elidedTemplate || semiEnd) {
        this->codeBlockAppend(result, '\n');
    }
    return result;
}

void IncludeParser::checkForMissingParams(const vector<string>& methodParams,
        const vector<string>& foundParams) {
    for (auto& methodParam : methodParams) {
        bool found = false;
        for (auto& foundParam : foundParams) {
            if (methodParam == foundParam) {
                found = true;
                break;
            }
        }
        if (!found) {
            this->writeIncompleteTag("Param", methodParam, 2);
        }
    }
    for (auto& foundParam : foundParams) {
        bool found = false;
        for (auto& methodParam : methodParams) {
            if (methodParam == foundParam) {
                found = true;
                break;
            }
        }
        if (!found) {
            this->reportError("doxygen param does not match method declaration");
        }
    }
}

bool IncludeParser::checkForWord() {
    if (!fIncludeWord) {
        return true;
    }
    KeyWord keyWord = FindKey(fIncludeWord, fChar);
    if (KeyWord::kClass == keyWord || KeyWord::kStruct == keyWord) {
        Bracket bracket = this->topBracket();
        if (Bracket::kParen == bracket) {
            return true;
        }
    }
    if (KeyWord::kNone != keyWord) {
        if (KeyProperty::kPreprocessor != kKeyWords[(int) keyWord].fProperty) {
            this->addKeyword(keyWord);
            return true;
        }
    } else {
        this->addWord();
        return true;
    }
    Definition* poundDef = fParent;
    if (!fParent) {
        return reportError<bool>("expected parent");
    }
    if (Definition::Type::kBracket != poundDef->fType) {
        return reportError<bool>("expected bracket");
    }
    if (Bracket::kPound != poundDef->fBracket) {
        return reportError<bool>("expected preprocessor");
    }
    if (KeyWord::kNone != poundDef->fKeyWord) {
        return reportError<bool>("already found keyword");
    }
    poundDef->fKeyWord = keyWord;
    fIncludeWord = nullptr;
    switch (keyWord) {
        // these do not link to other # directives
        case KeyWord::kDefine:
            if (!fInBrace) {
                SkASSERT(!fInDefine);
                fInDefine = true;
            }
        case KeyWord::kInclude:
        case KeyWord::kError:
        break;
        // these start a # directive link
        case KeyWord::kIf:
        case KeyWord::kIfdef:
        case KeyWord::kIfndef:
        break;
        // these continue a # directive link
        case KeyWord::kElif:
        case KeyWord::kElse:
            this->popObject();  // pop elif
            if (Bracket::kPound != fParent->fBracket) {
                return this->reportError<bool>("expected preprocessor directive");
            }
            this->popBracket();  // pop if
            poundDef->fParent = fParent;
            fParent = poundDef;  // push elif back
        break;
        // this ends a # directive link
        case KeyWord::kEndif:
        // FIXME : should this be calling popBracket() instead?
            this->popObject();  // pop endif
            if (Bracket::kPound != fParent->fBracket) {
                return this->reportError<bool>("expected preprocessor directive");
            }
            this->popBracket();  // pop if/else
        break;
        default:
            SkASSERT(0);
    }
    return true;
}

string IncludeParser::className() const {
    string name(fParent->fName);
    size_t slash = name.find_last_of("/");
    if (string::npos == slash) {
        slash = name.find_last_of("\\");
    }
    SkASSERT(string::npos != slash);
    string result = name.substr(slash);
    result = result.substr(1, result.size() - 3);
    return result;
}

void IncludeParser::writeCodeBlock() {
    fElided = Elided::kNo;
    for (auto& classMapper : fIClassMap) {
        fPreviousMarkType = MarkType::kNone;
        fPreviousDef = nullptr;
        classMapper.second.fCode = this->writeCodeBlock(classMapper.second);
    }
    for (auto& enumMapper : fIEnumMap) {
        fPreviousMarkType = MarkType::kNone;
        fPreviousDef = nullptr;
        enumMapper.second->fCode = this->writeCodeBlock(*enumMapper.second);
    }
    for (auto& typedefMapper : fITypedefMap) {
        fPreviousMarkType = MarkType::kNone;
        fPreviousDef = nullptr;
        typedefMapper.second->fCode = this->writeCodeBlock(*typedefMapper.second);
    }
    for (auto& defineMapper : fIDefineMap) {
        fPreviousMarkType = MarkType::kNone;
        fPreviousDef = nullptr;
        defineMapper.second->fCode = this->writeCodeBlock(*defineMapper.second);
    }
}

void IncludeParser::checkName(Definition* def) {
    SkASSERT(!def->fName.empty());
    TextParser parser(def->fFileName, &def->fName.front(), &def->fName.back() + 1, def->fLineCount);
    const vector<string> skipWords = { "deprecated", "experimental", "internal",  "private",
            "legacy", "temporary" };
    if (!parser.anyWord(skipWords, 0).empty()) {
        def->fUndocumented = true;
    }
}

#include <sstream>
#include <iostream>

void IncludeParser::checkTokens(list<Definition>& tokens, string key, string className,
        RootDefinition* root, BmhParser& bmhParser) {
    for (const auto& token : tokens) {
        if (token.fPrivate) {
            continue;
        }
        string fullName = key + "::" + token.fName;
        const Definition* def = nullptr;
        if (root) {
            def = root->find(fullName, RootDefinition::AllowParens::kYes);
        }
        switch (token.fMarkType) {
            case MarkType::kMethod: {
                if (this->isInternalName(token)) {
                    continue;
                }
                if (!root) {
                    if (token.fUndocumented) {
                        break;
                    }
                    auto methIter = bmhParser.fMethodMap.find(token.fName);
                    if (bmhParser.fMethodMap.end() != methIter) {
                        def = &methIter->second;
                        if (def->crossCheck2(token)) {
                            def->fVisited = true;
                        } else {
                            this->suggestFix(Suggest::kMethodDiffers, token, root, def);
                            fFailed = true;
                        }
                    } else {
                        this->suggestFix(Suggest::kMethodMissing, token, root, nullptr);
                        fFailed = true;
                    }
                    break;
                }
                if (!def) {
                    string paramName = className + "::";
                    paramName += string(token.fContentStart,
                            token.fContentEnd - token.fContentStart);
                    if (string::npos != paramName.find('\n')) {
                        paramName.erase(std::remove(paramName.begin(), paramName.end(), '\n'),
                                paramName.end());
                    }
                    def = root->find(paramName, RootDefinition::AllowParens::kYes);
                    if (!def && 0 == token.fName.find("operator")) {
                        string operatorName = className + "::";
                        TextParser oper("", token.fStart, token.fContentEnd, 0);
                        const char* start = oper.strnstr("operator", token.fContentEnd);
                        SkASSERT(start);
                        oper.skipTo(start);
                        oper.skipToEndBracket('(');
                        int parens = 0;
                        do {
                            if ('(' == oper.peek()) {
                                ++parens;
                            } else if (')' == oper.peek()) {
                                --parens;
                            }
                        } while (!oper.eof() && oper.next() && parens > 0);
                        operatorName += string(start, oper.fChar - start);
                        def = root->find(operatorName, RootDefinition::AllowParens::kYes);
                    }
                }
                if (!def) {
                    int skip = !strncmp(token.fContentStart, "explicit ", 9) ? 9 : 0;
                    skip = !strncmp(token.fContentStart, "virtual ", 8) ? 8 : skip;
                    const char* tokenEnd = token.methodEnd();
                    string constructorName = className + "::";
                    constructorName += string(token.fContentStart + skip,
                            tokenEnd - token.fContentStart - skip);
                    def = root->find(constructorName, RootDefinition::AllowParens::kYes);
                }
                if (!def && 0 == token.fName.find("SK_")) {
                    string incName = token.fName + "()";
                    string macroName = className + "::" + incName;
                    def = root->find(macroName, RootDefinition::AllowParens::kYes);
                    if (def) {
                        if (def->fName == incName) {
                            def->fVisited = true;
                            if ("SK_TO_STRING_NONVIRT" == token.fName) {
                                def = root->find(className + "::toString",
                                        RootDefinition::AllowParens::kYes);
                                if (def) {
                                    def->fVisited = true;
                                } else {
                                    SkDebugf("missing toString bmh: %s\n", fullName.c_str());
                                    fFailed = true;
                                }
                            }
                            break;
                        } else {
                            SkDebugf("method macro differs from bmh: %s\n", fullName.c_str());
                            fFailed = true;
                        }
                    }
                }
                if (!def) {
                    bool allLower = true;
                    for (size_t index = 0; index < token.fName.length(); ++index) {
                        if (!islower(token.fName[index])) {
                            allLower = false;
                            break;
                        }
                    }
                    if (allLower) {
                        string lowerName = className + "::" + token.fName + "()";
                        def = root->find(lowerName, RootDefinition::AllowParens::kYes);
                    }
                }
                if (!def) {
                    if (0 == token.fName.find("SkDEBUGCODE")) {
                        break;
                    }
                }
                if (!def) {
        // simple method names inside nested classes have a bug and are missing trailing parens
                    string withParens = fullName + "()"; // FIXME: this shouldn't be necessary
                    def = root->find(withParens, RootDefinition::AllowParens::kNo);
                }
                if (!def) {
                    if (!token.fUndocumented) {
                        this->suggestFix(Suggest::kMethodMissing, token, root, nullptr);
                        fFailed = true;
                    }
                    break;
                }
                if (token.fUndocumented) {
                    // we can't report an error yet; if bmh documents this unnecessarily,
                    // we'll detect that later. It may be that def points to similar
                    // documented function.
                    break;
                }
                if (def->crossCheck2(token)) {
                    def->fVisited = true;
                } else {
                    SkDebugf("method differs from bmh: %s\n", fullName.c_str());
                    fFailed = true;
                }
            } break;
            case MarkType::kComment:
                break;
            case MarkType::kEnumClass:
            case MarkType::kEnum: {
                if (!def) {
                    // work backwards from first word to deduce #Enum name
                    TextParser firstMember("", token.fStart, token.fContentEnd, 0);
                    SkAssertResult(firstMember.skipName("enum"));
                    SkAssertResult(firstMember.skipToEndBracket('{'));
                    firstMember.next();
                    firstMember.skipWhiteSpace();
                    SkASSERT('k' == firstMember.peek());
                    const char* savePos = firstMember.fChar;
                    firstMember.skipToNonName();
                    const char* wordEnd = firstMember.fChar;
                    firstMember.fChar = savePos;
                    const char* lastUnderscore = nullptr;
                    do {
                        if (!firstMember.skipToEndBracket('_')) {
                            break;
                        }
                        if (firstMember.fChar > wordEnd) {
                            break;
                        }
                        lastUnderscore = firstMember.fChar;
                    } while (firstMember.next());
                    if (lastUnderscore) {
                        ++lastUnderscore;
                        string enumName(lastUnderscore, wordEnd - lastUnderscore);
                        if (root) {
                            string anonName = className + "::" + enumName + 's';
                            def = root->find(anonName, RootDefinition::AllowParens::kYes);
                        } else {
                            auto enumIter = bmhParser.fEnumMap.find(enumName);
                            if (bmhParser.fEnumMap.end() != enumIter) {
                                RootDefinition* rootDef = &enumIter->second;
                                def = rootDef;
                            }
                        }
                    }
                    if (!def && !root) {
                        auto enumIter = bmhParser.fEnumMap.find(token.fName);
                        if (bmhParser.fEnumMap.end() != enumIter) {
                            def = &enumIter->second;
                        }
                        if (!def) {
                            auto enumClassIter = bmhParser.fClassMap.find(token.fName);
                            if (bmhParser.fClassMap.end() != enumClassIter) {
                                def = &enumClassIter->second;
                            }
                        }
                    }
                    if (!def) {
                        if (!token.fUndocumented) {
                            SkDebugf("enum missing from bmh: %s\n", fullName.c_str());
                            fFailed = true;
                        }
                        break;
                    }
                }
                def->fVisited = true;
                bool hasCode = false;
                bool hasPopulate = true;
                for (auto& child : def->fChildren) {
                    if (MarkType::kCode == child->fMarkType) {
                        hasPopulate = std::any_of(child->fChildren.begin(),
                                child->fChildren.end(), [](auto grandChild){
                                return MarkType::kPopulate == grandChild->fMarkType; });
                        if (!hasPopulate) {
                            def = child;
                        }
                        hasCode = true;
                        break;
                    }
                }
                if (!hasCode && !root) {
                    const Definition* topic = def->topicParent();
                    hasCode = std::any_of(topic->fChildren.begin(), topic->fChildren.end(),
                            [](Definition* def){ return MarkType::kCode == def->fMarkType
                            && def->fChildren.size() > 0 && MarkType::kPopulate ==
                            def->fChildren.front()->fMarkType; });
                }
                if (!hasCode) {
                    SkDebugf("enum code missing from bmh: %s\n", fullName.c_str());
                    fFailed = true;
                    break;
                }
                if (!hasPopulate) {
                    if (def->crossCheck(token)) {
                        def->fVisited = true;
                    } else {
                        SkDebugf("enum differs from bmh: %s\n", def->fName.c_str());
                        fFailed = true;
                    }
                }
                for (auto& member : token.fTokens) {
                    if (MarkType::kMember != member.fMarkType) {
                        continue;
                    }
                    string constName = MarkType::kEnumClass == token.fMarkType ?
                            fullName : className;
                    if (root) {
                        constName += "::" + member.fName;
                        def = root->find(constName, RootDefinition::AllowParens::kYes);
                    } else {
                        auto enumMapper = bmhParser.fEnumMap.find(token.fName);
                        if (bmhParser.fEnumMap.end() != enumMapper) {
                            auto& enumDoc = enumMapper->second;
                            auto memberIter = enumDoc.fLeaves.find(member.fName);
                            if (enumDoc.fLeaves.end() != memberIter) {
                                def = &memberIter->second;
                            }
                        }
                    }
                    if (!def) {
                        string innerName = key + "::" + member.fName;
                        def = root->find(innerName, RootDefinition::AllowParens::kYes);
                    }
                    if (!def) {
                        if (!member.fUndocumented) {
                            SkDebugf("const missing from bmh: %s\n", constName.c_str());
                            fFailed = true;
                        }
                    } else {
                        def->fVisited = true;
                    }
                }
                } break;
            case MarkType::kMember:
                if (def) {
                    def->fVisited = true;
                } else {
                    SkDebugf("member missing from bmh: %s\n", fullName.c_str());
                    fFailed = true;
                }
                break;
            case MarkType::kTypedef:
                if (!def && !root) {
                    auto typedefIter = bmhParser.fTypedefMap.find(token.fName);
                    if (bmhParser.fTypedefMap.end() != typedefIter) {
                        def = &typedefIter->second;
                    }
                }
                if (def) {
                    def->fVisited = true;
                } else {
                    SkDebugf("typedef missing from bmh: %s\n", fullName.c_str());
                    fFailed = true;
                }
                break;
            case MarkType::kConst:
                if (!def && !root) {
                    auto constIter = bmhParser.fConstMap.find(token.fName);
                    if (bmhParser.fConstMap.end() != constIter) {
                        def = &constIter->second;
                    }
                }
                if (def) {
                    def->fVisited = true;
                } else {
                    if (!token.fUndocumented) {
                        SkDebugf("const missing from bmh: %s\n", fullName.c_str());
                        fFailed = true;
                    }
                }
                break;
            case MarkType::kDefine:
                // TODO: incomplete
                break;
            default:
                SkASSERT(0);  // unhandled
                break;
        }
    }
}

bool IncludeParser::crossCheck(BmhParser& bmhParser) {
    for (auto& classMapper : fIClassMap) {
        string className = classMapper.first;
        auto finder = bmhParser.fClassMap.find(className);
        if (bmhParser.fClassMap.end() == finder) {
            SkASSERT(string::npos != className.find("::"));
            continue;
        }
    }
    for (auto& classMapper : fIClassMap) {
        if (classMapper.second.fUndocumented) {
           continue;
        }
        string className = classMapper.first;
        std::istringstream iss(className);
        string classStr;
        string classBase;
        RootDefinition* root = nullptr;
        while (std::getline(iss, classStr, ':')) {
            if (root) {
                if (!classStr.length()) {
                    continue;
                }
                classBase += "::" + classStr;
                auto finder = root->fBranches.find(classBase);
                if (root->fBranches.end() != finder) {
                    root = finder->second;
                } else {
                    SkASSERT(0);
                }
            } else {
                classBase = classStr;
                auto finder = bmhParser.fClassMap.find(classBase);
                if (bmhParser.fClassMap.end() != finder) {
                    root = &finder->second;
                } else {
                    SkASSERT(0);
                }
            }
        }
        this->checkTokens(classMapper.second.fTokens, classMapper.first, className, root,
                bmhParser);
    }
    this->checkTokens(fGlobals, "", "", nullptr, bmhParser);
    int crossChecks = 0;
    string firstCheck;
    for (auto& classMapper : fIClassMap) {
        string className = classMapper.first;
        auto finder = bmhParser.fClassMap.find(className);
        if (bmhParser.fClassMap.end() == finder) {
            continue;
        }
        RootDefinition* root = &finder->second;
        if (!root->dumpUnVisited()) {
            fFailed = true;
        }
        if (crossChecks) {
            SkDebugf(".");
        } else {
            SkDebugf("cross-check");
            firstCheck = className;
        }
        ++crossChecks;
    }
    if (crossChecks) {
        if (1 == crossChecks) {
            SkDebugf(" %s", firstCheck.c_str());
        }
        SkDebugf("\n");
    }
    bmhParser.fWroteOut = true;
    return !fFailed;
}

IClassDefinition* IncludeParser::defineClass(const Definition& includeDef,
        string name) {
    string className;
    const Definition* test = fParent;
    while (Definition::Type::kFileType != test->fType) {
        if (Definition::Type::kMark == test->fType && KeyWord::kClass == test->fKeyWord) {
            className = test->fName + "::";
            break;
        }
        test = test->fParent;
    }
    className += name;
    unordered_map<string, IClassDefinition>& map = fIClassMap;
    IClassDefinition& markupDef = map[className];
    if (markupDef.fStart) {
        typedef IClassDefinition* IClassDefPtr;
        return INHERITED::reportError<IClassDefPtr>("class already defined");
    }
    markupDef.fFileName = fFileName;
    markupDef.fStart = includeDef.fStart;
    markupDef.fContentStart = includeDef.fStart;
    markupDef.fName = className;
    this->checkName(&markupDef);
    markupDef.fContentEnd = includeDef.fContentEnd;
    markupDef.fTerminator = includeDef.fTerminator;
    markupDef.fParent = fParent;
    markupDef.fLineCount = fLineCount;
    markupDef.fMarkType = KeyWord::kStruct == includeDef.fKeyWord ?
            MarkType::kStruct : MarkType::kClass;
    markupDef.fKeyWord = includeDef.fKeyWord;
    markupDef.fType = Definition::Type::kMark;
    auto tokenIter = includeDef.fParent->fTokens.begin();
    SkASSERT(includeDef.fParentIndex > 0);
    std::advance(tokenIter, includeDef.fParentIndex - 1);
    const Definition* priorComment = &*tokenIter;
    markupDef.fUndocumented = priorComment->fUndocumented;
    fParent = &markupDef;
    return &markupDef;
}

void IncludeParser::dumpClassTokens(IClassDefinition& classDef) {
    auto& tokens = classDef.fTokens;
    bool wroteTail = true;
    for (auto& token : tokens) {
        if (Definition::Type::kMark == token.fType && MarkType::kComment == token.fMarkType) {
            continue;
        }
        if (wroteTail && MarkType::kMember != token.fMarkType) {
            this->writeBlockSeparator();
        }
        switch (token.fMarkType) {
            case MarkType::kConst:
                this->dumpConst(token, classDef.fName);
            break;
            case MarkType::kEnum:
            case MarkType::kEnumClass:
                this->dumpEnum(token, token.fName);
            break;
            case MarkType::kMethod:
                if (!this->dumpMethod(token, classDef.fName)) {
                    wroteTail = false;
                    continue;
                }
            break;
            case MarkType::kMember:
                this->dumpMember(token);
                continue;
            break;
            case MarkType::kTypedef:
                this->dumpTypedef(token, classDef.fName);
            break;
            default:
                SkASSERT(0);
        }
        this->dumpCommonTail(token);
        wroteTail = true;
    }
}
void IncludeParser::dumpComment(const Definition& token) {
    fLineCount = token.fLineCount;
    fChar = fLine = token.fContentStart;
    fEnd = token.fContentEnd;
    if (MarkType::kMethod == token.fMarkType) {
        this->lf(2);
        this->writeTag("Populate");
        this->lf(2);
        return;
    }
    for (const auto& child : token.fTokens) {
        if (Definition::Type::kMark == child.fType && MarkType::kMember == child.fMarkType) {
            break;
        }
        if (Definition::Type::kMark == child.fType && MarkType::kComment == child.fMarkType) {
            if (child.fPrivate) {
                break;
            }
            if (child.length() > 1) {
                const char* start = child.fContentStart;
                ptrdiff_t length = child.fContentEnd - start;
                SkASSERT(length >= 0);
                while (length && '/' == start[0]) {
                    start += 1;
                    --length;
                }
                while (length && '/' == start[length - 1]) {
                    length -= 1;
                    if (length && '*' == start[length - 1]) {
                        length -= 1;
                    }
                }
                if (length) {
                    this->lf(2);
                    if ("!< " == string(start, length).substr(0, 3)) {
                        return;
                    }
                    this->writeBlock(length, start);
                    this->lf(2);
                }
            }
        }
    }
}

void IncludeParser::dumpCommonTail(const Definition& token) {
    this->lf(2);
    this->writeTag("Example");
    this->lf(1);
    this->writeString("// incomplete");
    this->lf(1);
    this->writeEndTag();
    this->lf(2);
    this->writeTag("SeeAlso");
    this->writeSpace();
    this->writeString("incomplete");
    this->lf(2);
    this->writeEndTag(BmhParser::kMarkProps[(int) token.fMarkType].fName);
    this->lf(2);
}

void IncludeParser::dumpConst(const Definition& token, string className) {
    this->writeTag("Const");
    this->writeSpace();
    this->writeString(token.fName);
    this->writeTagTable("Line", "incomplete");
    this->lf(2);
    this->dumpComment(token);
}

void IncludeParser::dumpDefine(const Definition& token) {
    this->writeTag("Define", token.fName);
    this->lf(2);
    this->writeTag("Code");
    this->lfAlways(1);
    this->writeString("###$");
    this->lfAlways(1);
    this->indentToColumn(4);
    this->writeBlock(token.fTerminator - token.fStart, token.fStart);
    this->lf(1);
    this->indentToColumn(0);
    this->writeString("$$$#");

    this->writeEndTag();
    this->lf(2);
    this->dumpComment(token);
    for (auto& child : token.fTokens) {
        if (MarkType::kComment == child.fMarkType) {
            continue;
        }
        this->writeTag("Param", child.fName);
        this->writeSpace();
        this->writeString("incomplete");
        this->writeSpace();
        this->writeString("##");
        this->lf(1);
    }
}

void IncludeParser::dumpEnum(const Definition& token, string name) {
    string tagType(MarkType::kEnum == token.fMarkType ? "Enum" : "EnumClass");
    this->writeTag(tagType.c_str(), token.fName);
    this->lf(2);
    this->writeTag("Code");
    this->writeTag("Populate");
    this->writeEndTag();
    this->lf(2);
    this->dumpComment(token);
    string prior;
    for (auto& child : token.fTokens) {
        if (MarkType::kComment == child.fMarkType) {
            prior = string(child.fContentStart, child.length());
        }
        if (MarkType::kMember != child.fMarkType) {
            continue;
        }
        this->writeTag("Const");
        this->writeSpace();
        this->writeString(child.fName);
        this->writeSpace(2);
        this->writeString("0 # incomplete; replace '0' with member value");
        this->lf(1);
        this->writeTagNoLF("Line", "#");
        this->writeSpace();
        if ("/!< " == prior.substr(0, 4)) {
            this->writeString(prior.substr(4));
        } else {
            this->writeString("incomplete");
        }
        this->writeSpace();
        this->writeString("##");
        this->lf(1);
        this->writeString("# incomplete; add description or delete");
        this->writeEndTag();
    }
    this->lf(2);
    this->writeString("# incomplete; add description or delete");
    this->lf(2);
}

bool IncludeParser::dumpGlobals(string* globalFileName, long int* globalTell) {
    bool hasGlobals = !fIDefineMap.empty() || !fIFunctionMap.empty() || !fIEnumMap.empty()
            || !fITemplateMap.empty()|| !fITypedefMap.empty() || !fIUnionMap.empty();
    if (!hasGlobals) {
        return true;
    }
    size_t lastBSlash = fFileName.rfind('\\');
    size_t lastSlash = fFileName.rfind('/');
    size_t lastDotH = fFileName.rfind(".h");
    SkASSERT(string::npos != lastDotH);
    if (string::npos != lastBSlash && (string::npos == lastSlash
            || lastBSlash < lastSlash)) {
        lastSlash = lastBSlash;
    } else if (string::npos == lastSlash) {
        lastSlash = -1;
    }
    lastSlash += 1;
    string globalsName = fFileName.substr(lastSlash, lastDotH - lastSlash);
    string fileName = globalsName + "_Reference.bmh";
    *globalFileName = fileName;
    fOut = fopen(fileName.c_str(), "wb");
    if (!fOut) {
        SkDebugf("could not open output file %s\n", globalsName.c_str());
        return false;
    }
    string prefixName = globalsName.substr(0, 2);
    string topicName = globalsName.length() > 2 && isupper(globalsName[2]) &&
        ("Sk" == prefixName || "Gr" == prefixName) ? globalsName.substr(2) : globalsName;
    this->writeTagNoLF("Topic", topicName);
    this->writeEndTag("Alias", topicName + "_Reference");
    this->lf(2);
    if (!fIDefineMap.empty() || !fIFunctionMap.empty() || !fIEnumMap.empty()
            || !fITemplateMap.empty() || !fITypedefMap.empty() || !fIUnionMap.empty()) {
        this->writeTag("Code");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    std::map<int, Definition*> sortedDefs;
    for (const auto& entry : fIDefineMap) {
        sortedDefs[entry.second->fLineCount] = entry.second;
    }
    for (const auto& entry : fIFunctionMap) {
        sortedDefs[entry.second->fLineCount] = entry.second;
    }
    for (const auto& entry : fIEnumMap) {
        if (string::npos == entry.first.find("::")) {
            sortedDefs[entry.second->fLineCount] = entry.second;
        }
    }
    for (const auto& entry : fITemplateMap) {
        sortedDefs[entry.second->fLineCount] = entry.second;
    }
    for (const auto& entry : fITypedefMap) {
        sortedDefs[entry.second->fLineCount] = entry.second;
    }
    for (const auto& entry : fIUnionMap) {
        sortedDefs[entry.second->fLineCount] = entry.second;
    }
    for (const auto& entry : sortedDefs) {
        const Definition* def = entry.second;
        this->writeBlockSeparator();
        switch (def->fMarkType) {
            case MarkType::kDefine:
                this->dumpDefine(*def);
                break;
            case MarkType::kMethod:
                if (!this->dumpMethod(*def, globalsName)) {
                    continue;
                }
                break;
            case MarkType::kEnum:
            case MarkType::kEnumClass:
                this->dumpEnum(*def, globalsName);
                break;
            case MarkType::kTemplate:
                SkASSERT(0);  // incomplete
                break;
            case MarkType::kTypedef: {
                this->writeTag("Typedef");
                this->writeSpace();
                TextParser parser(def);
                if (!parser.skipExact("typedef")) {
                    return false;
                }
                if (!parser.skipSpace()) {
                    return false;
                }
                this->writeBlock(parser.fEnd - parser.fChar, parser.fChar);
                this->lf(2);
                this->dumpComment(*def);
                this->writeEndTag(BmhParser::kMarkProps[(int) entry.second->fMarkType].fName);
                this->lf(2);
                } continue;
            case MarkType::kUnion:
                SkASSERT(0);  // incomplete
                break;
            default:
                SkASSERT(0);
        }
        this->dumpCommonTail(*def);
    }
    *globalTell = ftell(fOut);
    this->writeEndTag("Topic", topicName);
    this->lfAlways(1);
//    fclose(fOut);     // defer closing in case class needs to be also written here
    return true;
}

bool IncludeParser::isClone(const Definition& token) {
    string name = token.fName;
    return name[name.length() - 2] == '_' && isdigit(name[name.length() - 1]);
}

bool IncludeParser::isConstructor(const Definition& token, string className) {
    string name = token.fName;
    return 0 == name.find(className) || '~' == name[0];
}

bool IncludeParser::isInternalName(const Definition& token) {
    string name = token.fName;
    // exception for this SkCanvas function .. for now
    if (0 == token.fName.find("androidFramework_setDeviceClipRestriction")) {
        return false;
    }
    return name.substr(0, 7) == "android"
            || 0 == token.fName.find("internal_")
            || 0 == token.fName.find("Internal_")
            || 0 == token.fName.find("legacy_")
            || 0 == token.fName.find("temporary_")
            || 0 == token.fName.find("private_");
}

bool IncludeParser::isMember(const Definition& token) const {
    if ('f' == token.fStart[0] && isupper(token.fStart[1])) {
        return true;
    }
    if (!islower(token.fStart[0])) {
        return false;
    }
    // make an exception for SkTextBlob::RunBuffer, sole struct with members not in fXxxx format
    if (string::npos != token.fFileName.find("SkTextBlob.h")) {
        const Definition* structToken = token.fParent;
        if (!structToken) {
            return false;
        }
        if (KeyWord::kStruct != structToken->fKeyWord) {
            structToken = token.fParent->fParent;
            if (!structToken) {
                return false;
            }
            if (KeyWord::kStruct != structToken->fKeyWord) {
                return false;
            }
        }
        SkASSERT(structToken->fTokens.size() > 0);
        const Definition& child = structToken->fTokens.front();
        string structName(child.fContentStart, child.length());
        if ("RunBuffer" != structName) {
            return false;
        }
        string tokenName(token.fContentStart, token.length());
        string allowed[] = { "glyphs", "pos", "utf8text", "clusters" };
        for (auto allow : allowed) {
            if (allow == tokenName) {
                return true;
            }
        }
    }
    return false;
}

bool IncludeParser::isOperator(const Definition& token) {
    return "operator" == token.fName.substr(0, 8);
}

bool IncludeParser::dumpMethod(const Definition& token, string className) {
    if (std::any_of(token.fTokens.begin(), token.fTokens.end(),
            [=](const Definition& def) { return MarkType::kComment == def.fMarkType
            && this->isUndocumentable(def.fFileName, def.fContentStart, def.fContentEnd,
            def.fLineCount); } )) {
        return false;
    }
    this->writeTag("Method");
    this->writeSpace();

    string name = string(token.fStart ? token.fStart : token.fContentStart,
            token.length());
    this->writeBlock((int) name.size(), name.c_str());
    string inType;
    if (this->isConstructor(token, className)) {
        inType = "Constructor";
    } else if (this->isOperator(token)) {
        inType = "Operator";
    } else {
        inType = "incomplete";
    }
    this->writeTag("In", inType);
    this->writeTagTable("Line", "incomplete");
    this->lf(2);
    this->dumpComment(token);
    return true;
}

void IncludeParser::dumpMember(const Definition& token) {
    this->writeTag("Member");
    this->writeSpace();
    this->writeDefinition(token, token.fName, 2);
    lf(1);
    for (auto child : token.fChildren) {
        this->writeDefinition(*child);
    }
    this->writeEndTag();
    lf(2);
}

bool IncludeParser::dumpTokens() {
    string globalFileName;
    long int globalTell = 0;
    if (!this->dumpGlobals(&globalFileName, &globalTell)) {
        return false;
    }
    for (const auto& member : fIClassMap) {
        if (string::npos != member.first.find("::")) {
            continue;
        }
        if (!this->dumpTokens(member.first, globalFileName, &globalTell)) {
            return false;
        }
    }
    if (globalTell) {
        fclose(fOut);
        SkDebugf("wrote %s\n", globalFileName.c_str());
    }
    return true;
}

    // dump equivalent markup
bool IncludeParser::dumpTokens(string skClassName, string globalFileName, long int* globalTell) {
    string fileName = skClassName + "_Reference.bmh";
    if (globalFileName != fileName) {
        fOut = fopen(fileName.c_str(), "wb");
        if (!fOut) {
            SkDebugf("could not open output file %s\n", fileName.c_str());
            return false;
        }
    } else {
        fseek(fOut, *globalTell, SEEK_SET);
        this->lf(2);
        this->writeBlockSeparator();
        *globalTell = 0;
    }
    string prefixName = skClassName.substr(0, 2);
    string topicName = skClassName.length() > 2 && isupper(skClassName[2]) &&
        ("Sk" == prefixName || "Gr" == prefixName) ? skClassName.substr(2) : skClassName;
    if (globalFileName != fileName) {
        this->writeTagNoLF("Topic", topicName);
        this->writeEndTag("Alias", topicName + "_Reference");
        this->lf(2);
    }
    auto& classMap = fIClassMap[skClassName];
    SkASSERT(KeyWord::kClass == classMap.fKeyWord || KeyWord::kStruct == classMap.fKeyWord);
    const char* containerType = KeyWord::kClass == classMap.fKeyWord ? "Class" : "Struct";
    this->writeTag(containerType, skClassName);
    this->lf(2);
    auto& tokens = classMap.fTokens;
    for (auto& token : tokens) {
        if (Definition::Type::kMark != token.fType || MarkType::kComment != token.fMarkType) {
            continue;
        }
        this->writeDefinition(token);
        this->lf(1);
    }
    this->lf(2);
    this->writeTag("Code");
    this->writeTag("Populate");
    this->writeEndTag();
    this->lf(2);
    for (auto& oneClass : fIClassMap) {
        if (skClassName + "::" != oneClass.first.substr(0, skClassName.length() + 2)) {
            continue;
        }
        string innerName = oneClass.first.substr(skClassName.length() + 2);
        this->writeBlockSeparator();
        KeyWord keyword = oneClass.second.fKeyWord;
        SkASSERT(KeyWord::kClass == keyword || KeyWord::kStruct == keyword);
        const char* containerType = KeyWord::kClass == keyword ? "Class" : "Struct";
        this->writeTag(containerType, innerName);
        this->writeTagTable("Line", "incomplete");
        this->lf(2);
        this->writeTag("Code");
        this->writeEndTag("ToDo", "fill this in manually");
        this->writeEndTag();
        this->lf(2);
        for (auto& token : oneClass.second.fTokens) {
            if (Definition::Type::kMark != token.fType || MarkType::kComment != token.fMarkType) {
                continue;
            }
            this->writeDefinition(token);
        }
        this->lf(2);
        this->dumpClassTokens(oneClass.second);
        this->lf(2);
        this->writeEndTag(containerType, innerName);
        this->lf(2);
    }
    this->dumpClassTokens(classMap);
    this->writeEndTag(containerType, skClassName);
    this->lf(2);
    this->writeEndTag("Topic", topicName);
    this->lfAlways(1);
    fclose(fOut);
    SkDebugf("wrote %s\n", fileName.c_str());
    return true;
}

void IncludeParser::dumpTypedef(const Definition& token, string className) {
    this->writeTag("Typedef");
    this->writeSpace();
    this->writeString(token.fName);
    this->writeTagTable("Line", "incomplete");
    this->lf(2);
    this->dumpComment(token);
}

string IncludeParser::elidedCodeBlock(const Definition& iDef) {
    SkASSERT(KeyWord::kStruct == iDef.fKeyWord || KeyWord::kClass == iDef.fKeyWord
            || KeyWord::kTemplate == iDef.fKeyWord);
    TextParser i(&iDef);
    fElided = Elided::kYes;
    MarkType markType = MarkType::kClass;
    if (KeyWord::kTemplate == iDef.fKeyWord) {  // may be function
        for (auto child : iDef.fChildren) {
            if (MarkType::kMethod == child->fMarkType) {
                markType = MarkType::kFunction;
                break;
            }
        }
    }
    return this->writeCodeBlock(i, markType, 0);
}

 string IncludeParser::filteredBlock(string inContents, string filterContents) {
    string result;
    const unordered_map<string, Definition*>* mapPtr = nullptr;
    if ("Constant" == inContents) {
        mapPtr = &fIConstMap;
    } else {
        SkASSERT(0); // only Constant supported for now
    }
    vector<Definition*> consts;
    for (auto entry : *mapPtr) {
        if (string::npos == entry.first.find(filterContents)) {
            continue;
        }
        consts.push_back(entry.second);
    }
    std::sort(consts.begin(), consts.end(), [](Definition* def1, Definition* def2) {
        return def1->fLineCount < def2->fLineCount;
    } );
    for (auto oneConst : consts) {
        result += this->writeCodeBlock(*oneConst);
    }
    return result;
}

bool IncludeParser::findCommentAfter(const Definition& includeDef, Definition* markupDef) {
    this->checkName(markupDef);
    const Definition* parent = includeDef.fParent;
    int index = includeDef.fParentIndex;
    auto wordIter = parent->fTokens.begin();
    std::advance(wordIter, index);
    SkASSERT(&*wordIter == &includeDef);
    size_t commentLine = 0;
    do {
        wordIter = std::next(wordIter);
        if (parent->fTokens.end() == wordIter) {
            break;
        }
        commentLine = wordIter->fLineCount;
    } while (Punctuation::kSemicolon != wordIter->fPunctuation);
    wordIter = std::next(wordIter);
    if (parent->fTokens.end() != wordIter && Bracket::kSlashSlash == wordIter->fBracket
            && wordIter->fLineCount == commentLine) {
        return this->parseComment(wordIter->fFileName, wordIter->fContentStart,
                wordIter->fContentEnd, wordIter->fLineCount, markupDef, &markupDef->fUndocumented);
    }
    return true;
}

bool IncludeParser::findComments(const Definition& includeDef, Definition* markupDef) {
    this->checkName(markupDef);
    // add comment preceding class, if any
    Definition* parent = includeDef.fParent;
    int index = includeDef.fParentIndex;
    auto wordIter = parent->fTokens.begin();
    std::advance(wordIter, index);
    SkASSERT(&*wordIter == &includeDef);
    while (parent->fTokens.begin() != wordIter) {
        auto testIter = std::prev(wordIter);
        if (Definition::Type::kWord != testIter->fType
            && Definition::Type::kKeyWord != testIter->fType
            && (Definition::Type::kBracket != testIter->fType
            || Bracket::kAngle != testIter->fBracket)
            && (Definition::Type::kPunctuation != testIter->fType
            || Punctuation::kAsterisk != testIter->fPunctuation)) {
            break;
        }
        wordIter = testIter;
    }
    auto commentIter = wordIter;
    while (parent->fTokens.begin() != commentIter) {
        auto testIter = std::prev(commentIter);
        bool isComment = Definition::Type::kBracket == testIter->fType
                && (Bracket::kSlashSlash == testIter->fBracket
                || Bracket::kSlashStar == testIter->fBracket);
        if (!isComment) {
            break;
        }
        commentIter = testIter;
    }
    while (commentIter != wordIter) {
        if (!this->parseComment(commentIter->fFileName, commentIter->fContentStart,
                commentIter->fContentEnd, commentIter->fLineCount, markupDef,
                &markupDef->fUndocumented)) {
            return false;
        }
        commentIter->fUndocumented = markupDef->fUndocumented;
        commentIter = std::next(commentIter);
    }
    return true;
}

Definition* IncludeParser::findIncludeObject(const Definition& includeDef, MarkType markType,
        string typeName) {
    typedef Definition* DefinitionPtr;
    auto mapIter = std::find_if(fMaps.begin(), fMaps.end(),
            [markType](DefinitionMap& defMap){ return markType == defMap.fMarkType; } );
    if (mapIter == fMaps.end()) {
        return nullptr;
    }
    if (mapIter->fInclude->end() == mapIter->fInclude->find(typeName)) {
        return reportError<DefinitionPtr>("invalid mark type");
    }
    string name = this->uniqueName(*mapIter->fInclude, typeName);
    Definition& markupDef = *(*mapIter->fInclude)[name];
    if (markupDef.fStart) {
        return reportError<DefinitionPtr>("definition already defined");
    }
    markupDef.fFileName = fFileName;
    markupDef.fStart = includeDef.fStart;
    markupDef.fContentStart = includeDef.fStart;
    this->checkName(&markupDef);
    markupDef.fName = name;
    markupDef.fContentEnd = includeDef.fContentEnd;
    markupDef.fTerminator = includeDef.fTerminator;
    markupDef.fParent = fParent;
    markupDef.fLineCount = includeDef.fLineCount;
    markupDef.fMarkType = markType;
    markupDef.fKeyWord = includeDef.fKeyWord;
    markupDef.fType = Definition::Type::kMark;
    return &markupDef;
}

Definition* IncludeParser::findMethod(const Definition& bmhDef) {
    auto doubleColon = bmhDef.fName.rfind("::");
    if (string::npos == doubleColon) {
        const auto& iGlobalMethod = fIFunctionMap.find(bmhDef.fName);
        SkASSERT(fIFunctionMap.end() != iGlobalMethod);
        return iGlobalMethod->second;
    }
    string className = bmhDef.fName.substr(0, doubleColon);
    const auto& iClass = fIClassMap.find(className);
    if (fIClassMap.end() == iClass) {
        return nullptr;
    }
    string methodName = bmhDef.fName.substr(doubleColon + 2);
    auto& iTokens = iClass->second.fTokens;
    const auto& iMethod = std::find_if(iTokens.begin(), iTokens.end(),
            [methodName](Definition& token) {
            return MarkType::kMethod == token.fMarkType
                    && !token.fUndocumented
                    && (methodName == token.fName
                    || methodName == token.fName + "()"); } );
    if (iTokens.end() != iMethod) {
        return &*iMethod;
    }
    size_t subClassPos = className.rfind("::");
    if (string::npos != subClassPos) {
        className = className.substr(subClassPos + 2);
    }
    // match may be constructor; compare strings to see if this is so
    if (string::npos == methodName.find('(')) {
        return nullptr;
    }
    auto stripper = [](string s) -> string {
        bool last = false;
        string result;
        for (char c : s) {
            if (' ' >= c) {
                if (!last) {
                    last = true;
                    result += ' ';
                }
                continue;
            }
            result += c;
            last = false;
        }
        return result;
    };
    string strippedMethodName = stripper(methodName);
    if (strippedMethodName == methodName) {
        strippedMethodName = "";
    }
    const auto& cMethod = std::find_if(iTokens.begin(), iTokens.end(),
            [className, methodName, stripper, strippedMethodName](Definition& token) {
        if (MarkType::kMethod != token.fMarkType) {
            return false;
        }
        if (token.fUndocumented) {
            return false;
        }
        TextParser parser(&token);
        const char* match = parser.strnstr(className.c_str(), parser.fEnd);
        if (!match) {
            return false;
        }
        parser.skipTo(match);
        parser.skipExact(className.c_str());
        if ('(' != parser.peek()) {
            return false;
        }
        parser.skipToBalancedEndBracket('(', ')');
        string iMethodName(match, parser.fChar - match);
        if (methodName == iMethodName) {
            return true;
        }
        if (strippedMethodName.empty()) {
            return false;
        }
        string strippedIName = stripper(iMethodName);
        return strippedIName == strippedMethodName;
    } );
    SkAssertResult(iTokens.end() != cMethod);
    return &*cMethod;
}

Definition* IncludeParser::parentBracket(Definition* parent) const {
    while (parent && Definition::Type::kBracket != parent->fType) {
        parent = parent->fParent;
    }
    return parent;
}

Bracket IncludeParser::grandParentBracket() const {
    Definition* parent = parentBracket(fParent);
    parent = parentBracket(parent ? parent->fParent : nullptr);
    return parent ? parent->fBracket : Bracket::kNone;
}

bool IncludeParser::inAlignAs() const {
    if (fParent->fTokens.size() < 2) {
        return false;
    }
    auto reverseIter = fParent->fTokens.end();
    bool checkForBracket = true;
    while (fParent->fTokens.begin() != reverseIter) {
        std::advance(reverseIter, -1);
        if (checkForBracket) {
            if (Definition::Type::kBracket != reverseIter->fType) {
                return false;
            }
            if (Bracket::kParen != reverseIter->fBracket) {
                return false;
            }
            checkForBracket = false;
            continue;
        }
        if (Definition::Type::kKeyWord != reverseIter->fType) {
            return false;
        }
        return KeyWord::kAlignAs == reverseIter->fKeyWord;
    }
    return false;
}

const Definition* IncludeParser::include(string match) const {
    for (auto& entry : fIncludeMap) {
        if (string::npos == entry.first.find(match)) {
            continue;
        }
        return &entry.second;
    }
    SkASSERT(0);
    return nullptr;
}

// caller just returns, so report error here
bool IncludeParser::parseClass(Definition* includeDef, IsStruct isStruct) {
    SkASSERT(includeDef->fTokens.size() > 0);
    // parse class header
    auto iter = includeDef->fTokens.begin();
    if (!strncmp(iter->fStart, "SK_API", iter->fContentEnd - iter->fStart)) {
        // todo : documentation is ignoring this for now
        iter = std::next(iter);
    }
    bool hasAlignAs = iter->fKeyWord == KeyWord::kAlignAs;
    if (hasAlignAs) {
        iter = std::next(iter);
        if (Definition::Type::kBracket != iter->fType || Bracket::kParen != iter->fBracket) {
            return includeDef->reportError<bool>("expected alignas argument");
        }
        iter = std::next(iter);
    }
    string nameStr(iter->fStart, iter->fContentEnd - iter->fStart);
    includeDef->fName = nameStr;
    this->checkName(includeDef);
    iter = std::next(iter);
    if (iter == includeDef->fTokens.end()) {
        return true;  // forward declaration only
    }
    do {
        if (iter == includeDef->fTokens.end()) {
            return includeDef->reportError<bool>("unexpected end");
        }
        if ('{' == iter->fStart[0] && Definition::Type::kPunctuation == iter->fType) {
            break;
        }
    } while (static_cast<void>(iter = std::next(iter)), true);
    if (Punctuation::kLeftBrace != iter->fPunctuation) {
        return iter->reportError<bool>("expected left brace");
    }
    IClassDefinition* markupDef = this->defineClass(*includeDef, nameStr);
    if (!markupDef) {
        return iter->reportError<bool>("expected markup definition");
    }
    markupDef->fStart = iter->fStart;
    if (!this->findComments(*includeDef, markupDef)) {
        return iter->reportError<bool>("find comments failed");
    }
    if (markupDef->fUndocumented) {
        includeDef->fUndocumented = true;
    }
//    if (1 != includeDef->fChildren.size()) {
//        return false;  // fix me: SkCanvasClipVisitor isn't correctly parsed
//    }
    auto includeDefIter = includeDef->fChildren.begin();
    if (hasAlignAs) {
        SkASSERT(includeDef->fChildren.end() != includeDefIter);
        SkASSERT(Bracket::kParen == (*includeDefIter)->fBracket);
        std::advance(includeDefIter, 1);
    }
    if (includeDef->fChildren.end() != includeDefIter
            && Bracket::kAngle == (*includeDefIter)->fBracket) {
        std::advance(includeDefIter, 1);
    }
    includeDef = *includeDefIter;
    SkASSERT(Bracket::kBrace == includeDef->fBracket);
    iter = includeDef->fTokens.begin();
    // skip until public
    int publicIndex = 0;
    if (IsStruct::kNo == isStruct) {
        const char* publicName = kKeyWords[(int) KeyWord::kPublic].fName;
        size_t publicLen = strlen(publicName);
        while (iter != includeDef->fTokens.end()
                && (publicLen != (size_t) (iter->fContentEnd - iter->fStart)
                || strncmp(iter->fStart, publicName, publicLen))) {
            iter->fPrivate = true;
            iter = std::next(iter);
            ++publicIndex;
        }
    }
    int keyIndex = publicIndex;
    KeyWord currentKey = KeyWord::kPublic;
    const char* publicName = kKeyWords[(int) KeyWord::kPublic].fName;
    size_t publicLen = strlen(publicName);
    const char* protectedName = kKeyWords[(int) KeyWord::kProtected].fName;
    size_t protectedLen = strlen(protectedName);
    const char* privateName = kKeyWords[(int) KeyWord::kPrivate].fName;
    size_t privateLen = strlen(privateName);
    auto childIter = includeDef->fChildren.begin();
    while (includeDef->fChildren.end() != childIter && (*childIter)->fPrivate) {
        std::advance(childIter, 1);
    }
    while (childIter != includeDef->fChildren.end()) {
        Definition* child = *childIter;
        while (child->fParentIndex > keyIndex && iter != includeDef->fTokens.end()) {
            iter->fPrivate = KeyWord::kPublic != currentKey;
            const char* testStart = iter->fStart;
            size_t testLen = (size_t) (iter->fContentEnd - testStart);
            iter = std::next(iter);
            ++keyIndex;
            if (publicLen == testLen && !strncmp(testStart, publicName, testLen)) {
                currentKey = KeyWord::kPublic;
                break;
            }
            if (protectedLen == testLen && !strncmp(testStart, protectedName, testLen)) {
                currentKey = KeyWord::kProtected;
                break;
            }
            if (privateLen == testLen && !strncmp(testStart, privateName, testLen)) {
                currentKey = KeyWord::kPrivate;
                break;
            }
        }
        fLastObject = nullptr;
        if (KeyWord::kPublic == currentKey) {
            if (!this->parseObject(child, markupDef)) {
                return false;
            }
        }
        fLastObject = child;
        childIter = std::next(childIter);
    }
    while (iter != includeDef->fTokens.end()) {
        iter->fPrivate = KeyWord::kPublic != currentKey;
        iter = std::next(iter);
    }
    SkASSERT(fParent->fParent);
    fParent = fParent->fParent;
    return true;
}

bool IncludeParser::isUndocumentable(string filename, const char* start, const char* end,
        int lineCount) {
    TextParser parser(filename, start, end, lineCount);
    const vector<string> skipWords = { "deprecated", "experimental", "private" };
    const vector<string> butNot = { "to be deprecated", "may be deprecated" };
    const vector<string> alsoNot = { "todo" };
    string match = parser.anyWord(skipWords, 0);
    if ("" != match) {
        if (parser.anyWord(alsoNot, 0).empty()
                && ("deprecated" != match || parser.anyWord(butNot, 2).empty())) {
            return true;
        }
    }
    return false;
}

bool IncludeParser::parseComment(string filename, const char* start, const char* end,
        int lineCount, Definition* markupDef, bool* undocumentedPtr) {
    if (this->isUndocumentable(filename, start, end, lineCount)) {
        *undocumentedPtr = true;
    }
    // parse doxygen if present
    TextParser parser(filename, start, end, lineCount);
    if (parser.startsWith("**")) {
        parser.next();
        parser.next();
        parser.skipWhiteSpace();
        if ('\\' == parser.peek()) {
            parser.next();
            // Doxygen tag may be "file" or "fn" in addition to "class", "enum", "struct"
            if (parser.skipExact("file")) {
                if (Definition::Type::kFileType != fParent->fType) {
                    return reportError<bool>("expected parent is file");
                }
                string filename = markupDef->fileName();
                if (!parser.skipWord(filename.c_str())) {
                    return reportError<bool>("missing object type");
                }
            } else if (parser.skipExact("fn")) {
                SkASSERT(0);  // incomplete
            } else {
                if (!parser.skipWord(kKeyWords[(int) markupDef->fKeyWord].fName)) {
                    return reportError<bool>("missing object type");
                }
                if (!parser.skipWord(markupDef->fName.c_str()) &&
                        KeyWord::kEnum != markupDef->fKeyWord) {
                    return reportError<bool>("missing object name");
                }
            }
        }
    }
    // remove leading '*' if present
    Definition* parent = markupDef->fTokens.size() ? &markupDef->fTokens.back() : markupDef;
    while (!parser.eof() && parser.skipWhiteSpace()) {
        while ('*' == parser.peek()) {
            parser.next();
            if (parser.eof()) {
                break;
            }
            parser.skipWhiteSpace();
        }
        if (parser.eof()) {
            break;
        }
        const char* lineEnd = parser.trimmedLineEnd();
        markupDef->fTokens.emplace_back(MarkType::kComment, parser.fChar, lineEnd,
                parser.fLineCount, parent, '\0');
        parser.skipToEndBracket('\n');
    }
    return true;
}

/*
    find comment either in front of or after the const def and then extract if the
    const is undocumented
 */
bool IncludeParser::parseConst(Definition* child, Definition* markupDef) {
    if (!markupDef) {
        fGlobals.emplace_back(MarkType::kConst, child->fContentStart, child->fContentEnd,
                child->fLineCount, fParent, '\0');
        Definition* globalMarkupChild = &fGlobals.back();
        string globalUniqueName = this->uniqueName(fIConstMap, child->fName);
        globalMarkupChild->fName = globalUniqueName;
        if (!this->findComments(*child, globalMarkupChild)) {
            return false;
        }
        if (!this->findCommentAfter(*child, globalMarkupChild)) {
            return false;
        }
        if (globalMarkupChild->fUndocumented) {
            child->fUndocumented = true;
        } else {
            fIConstMap[globalUniqueName] = globalMarkupChild;
        }
        return true;
    }
    markupDef->fTokens.emplace_back(MarkType::kConst, child->fContentStart, child->fContentEnd,
        child->fLineCount, markupDef, '\0');
    Definition* markupChild = &markupDef->fTokens.back();
    markupChild->fName = child->fName;
    markupChild->fTerminator = markupChild->fContentEnd;
    IClassDefinition& classDef = fIClassMap[markupDef->fName];
    classDef.fConsts[child->fName] = markupChild;
    if (!this->findComments(*child, markupChild)) {
        return false;
    }
    if (!this->findCommentAfter(*child, markupChild)) {
        return false;
    }
    if (markupChild->fUndocumented) {
        child->fUndocumented = true;
    } else {
        fIConstMap[child->fName] = markupChild;
    }
    return true;
}

bool IncludeParser::parseDefine(Definition* child, Definition* markupDef) {
    TextParser parser(child);
    if (!parser.skipExact("#define")) {
        return false;
    }
    if (!parser.skipSpace()) {
        return false;
    }
    const char* nameStart = parser.fChar;
    parser.skipToNonAlphaNum(); // FIXME: just want to skip isalnum() and '_'
    if (parser.eof()) {
        return true;    // do nothing if #define doesn't define anything
    }
    string nameStr(nameStart, parser.fChar - nameStart);
    struct Param {
        const char* fStart;
        const char* fEnd;
    };
    vector<Param> params;
    if ('(' == parser.peek()) {
        parser.next();
        if (!parser.skipSpace()) {
            return false;
        }
        do {
            const char* paramStart = parser.fChar;
            if (!parser.skipExact("...")) {
                parser.skipToNonAlphaNum();
            }
            if (parser.eof()) {
                return false;
            }
            params.push_back({paramStart, parser.fChar});
            if (!parser.skipSpace()) {
                return false;
            }
            if (')' == parser.peek()) {
                parser.next();
                break;
            }
            if (',' != parser.next()) {
                return false;
            }
            if (!parser.skipSpace()) {
                return false;
            }
        } while (true);
    }
    if (!parser.skipSpace()) {
        return false;
    }
    if (!markupDef) {
        fGlobals.emplace_back(MarkType::kDefine, nameStart, child->fContentEnd,
                child->fLineCount, fParent, '\0');
        Definition* globalMarkupChild = &fGlobals.back();
        string globalUniqueName = this->uniqueName(fIDefineMap, nameStr);
        globalMarkupChild->fName = globalUniqueName;
        globalMarkupChild->fTerminator = child->fContentEnd;
        if (!this->findComments(*child, globalMarkupChild)) {
            return false;
        }
        if (!globalMarkupChild->fUndocumented) {
            fIDefineMap[globalUniqueName] = globalMarkupChild;
        }
        for (Param param : params) {
            globalMarkupChild->fTokens.emplace_back(MarkType::kParam, param.fStart, param.fEnd,
                    child->fLineCount, globalMarkupChild, '\0');
            Definition* paramChild = &globalMarkupChild->fTokens.back();
            paramChild->fName = string(param.fStart, param.fEnd - param.fStart);
            this->checkName(paramChild);
            paramChild->fTerminator = param.fEnd;
        }
        return true;
    }
    markupDef->fTokens.emplace_back(MarkType::kDefine, child->fContentStart, child->fContentEnd,
            child->fLineCount, markupDef, '\0');
    Definition* markupChild = &markupDef->fTokens.back();
    markupChild->fName = nameStr;
    markupChild->fTerminator = markupChild->fContentEnd;
    IClassDefinition& classDef = fIClassMap[markupDef->fName];
    if (!this->findComments(*child, markupChild)) {
        return false;
    }
    if (markupChild->fUndocumented) {
        child->fUndocumented = true;
    } else {
        classDef.fDefines[nameStr] = markupChild;
        fIDefineMap[nameStr] = markupChild;
    }
    return true;
}

bool IncludeParser::parseEnum(Definition* child, Definition* markupDef) {
	if (!child->fTokens.size()) {
		return true;	// if enum is a forward declaration, do nothing
	}
    bool isEnumClass = false;
    Definition* parent = child;
    auto token = parent->fTokens.begin();
    if (Definition::Type::kKeyWord == token->fType && KeyWord::kClass == token->fKeyWord) {
        isEnumClass = true;
        parent = &*token;
        token = parent->fTokens.begin();
    }
    SkASSERT(Definition::Type::kWord == token->fType);
    string nameStr = string(token->fStart, token->fContentEnd - token->fStart);
    Definition* markupChild;
    if (!markupDef) {
        fGlobals.emplace_back(MarkType::kEnum, child->fContentStart, child->fContentEnd,
                child->fLineCount, fParent, '\0');
        markupChild = &fGlobals.back();
        string globalUniqueName = this->uniqueName(fIEnumMap, nameStr);
        markupChild->fName = globalUniqueName;
        markupChild->fTerminator = child->fContentEnd;
        if (!markupChild->fUndocumented) {
            fIEnumMap[globalUniqueName] = markupChild;
        }
    } else {
        markupDef->fTokens.emplace_back(MarkType::kEnum, child->fContentStart, child->fContentEnd,
            child->fLineCount, markupDef, '\0');
        markupChild = &markupDef->fTokens.back();
    }
    SkASSERT(KeyWord::kNone == markupChild->fKeyWord);
    markupChild->fKeyWord = KeyWord::kEnum;
    if (isEnumClass) {
        markupChild->fMarkType = MarkType::kEnumClass;
    }
    if (markupDef) {
        markupChild->fName = markupDef->fName + "::" + nameStr;
    }
    if (!this->findComments(*child, markupChild)) {
        return false;
    }
    if (markupChild->fUndocumented) {
        child->fUndocumented = true;
    }
    if (!this->parseEnumConst(token, parent->fTokens.end(), markupChild)) {
        return false;
    }
    for (auto outsideMember : child->fChildren) {
        if (Definition::Type::kBracket == outsideMember->fType) {
            continue;
        }
        SkASSERT(Definition::Type::kKeyWord == outsideMember->fType);
        if (KeyWord::kClass == outsideMember->fKeyWord) {
            continue;
        }
        SkASSERT(KeyWord::kStatic == outsideMember->fKeyWord);
        markupChild->fTokens.emplace_back(MarkType::kMember, outsideMember->fContentStart,
                outsideMember->fContentEnd, outsideMember->fLineCount, markupChild, '\0');
        Definition* member = &markupChild->fTokens.back();
        member->fName = outsideMember->fName;
        this->checkName(member);
        // FIXME: ? add comment as well ?
        markupChild->fChildren.push_back(member);
    }
    if (markupDef) {
        IClassDefinition& classDef = fIClassMap[markupDef->fName];
        SkASSERT(classDef.fStart);
        string uniqueName = this->uniqueName(classDef.fEnums, nameStr);
        string fullName = markupChild->fName;
        markupChild->fName = uniqueName;
        classDef.fEnums[uniqueName] = markupChild;
        if (!markupChild->fUndocumented) {
            fIEnumMap[fullName] = markupChild;
        }
    }
    return true;
}

bool IncludeParser::parseOneEnumConst(list<Definition>& constList,
        Definition* markupChild, bool skipWord) {
    auto memberIter = constList.begin();
    const auto memberIterEnd = constList.end();
    if (skipWord) {
        SkASSERT(Definition::Type::kWord == memberIter->fType);
        memberIter = std::next(memberIter);
        SkASSERT(memberIterEnd != memberIter);
    }
    // token array has parse atoms; child array has comments
    bool undocumented = false;
    while (memberIterEnd != memberIter) {
        while (Bracket::kSlashStar == memberIter->fBracket) {
            if (!this->parseComment(memberIter->fFileName, memberIter->fContentStart,
                    memberIter->fContentEnd, memberIter->fLineCount, markupChild, &undocumented)) {
                return false;
            }
            memberIter = std::next(memberIter);
            if (memberIterEnd == memberIter) {
                return false;
            }
        }
        if (Bracket::kPound == memberIter->fBracket) {
            KeyWord keyWord = memberIter->fKeyWord;
            bool sawIf = KeyWord::kIfdef == keyWord || KeyWord::kIf == keyWord
                    || KeyWord::kElif == keyWord;
            if (sawIf || KeyWord::kElse == keyWord) {
                if (!parseOneEnumConst(memberIter->fTokens, markupChild, sawIf)) {
                    return false;
                }
            } else {
                SkASSERT(KeyWord::kEndif == keyWord || KeyWord::kError == keyWord);
            }
            memberIter = std::next(memberIter);
            if (memberIterEnd == memberIter) {
                break;
            }
            continue;
        }
        while (Definition::Type::kWord != memberIter->fType) {
            memberIter = std::next(memberIter);
            if (memberIterEnd == memberIter) {
                return false;
            }
        }
        auto memberStart = memberIter;
        Definition* memberEnd = nullptr;
        const char* last;
        do {
            last = memberIter->fContentEnd;
            memberIter = std::next(memberIter);
            if (memberIterEnd == memberIter) {
                break;
            }
            memberEnd = &*memberIter;
        } while (string::npos == string(last, memberIter->fContentStart).find(','));
        if (!memberEnd) {
            return false;
        }
        if (memberIterEnd != memberIter && Bracket::kSlashSlash == memberIter->fBracket) {
            if (!this->parseComment(memberIter->fFileName, memberIter->fContentStart,
                    memberIter->fContentEnd, memberIter->fLineCount, markupChild, &undocumented)) {
                return false;
            }
            memberIter = std::next(memberIter);
        }
        markupChild->fTokens.emplace_back(MarkType::kMember, memberStart->fContentStart,
                memberEnd->fContentEnd, memberStart->fLineCount, markupChild, '\0');
        Definition* markupMember = &markupChild->fTokens.back();
        string name = string(memberStart->fContentStart, memberStart->length());
        memberStart->fName = name;
        markupMember->fName = name;
        this->checkName(markupMember);
        memberStart->fUndocumented = markupMember->fUndocumented;
        memberStart->fMarkType = MarkType::kMember;
        undocumented = false;
    }
    return true;
}

bool IncludeParser::parseEnumConst(list<Definition>::iterator& tokenIter,
        const list<Definition>::iterator& tokenEnd, Definition* markupChild) {
    SkASSERT(Definition::Type::kWord == tokenIter->fType);  // should be enum name
    tokenIter = std::next(tokenIter);
    SkASSERT(tokenEnd != tokenIter);
    if (Definition::Type::kKeyWord == tokenIter->fType) {
        SkASSERT((unsigned) tokenIter->fKeyWord < SK_ARRAY_COUNT(kKeyWords));
        SkASSERT(KeyProperty::kNumber == kKeyWords[(int) tokenIter->fKeyWord].fProperty);
        tokenIter = std::next(tokenIter);
        SkASSERT(tokenEnd != tokenIter);
    }
    SkASSERT(Punctuation::kLeftBrace == tokenIter->fPunctuation);
    tokenIter = std::next(tokenIter);
    SkASSERT(tokenEnd != tokenIter);
    SkASSERT(Bracket::kBrace == tokenIter->fBracket);
    return parseOneEnumConst(tokenIter->fTokens, markupChild, false);
}

bool IncludeParser::parseInclude(string name) {
    fParent = &fIncludeMap[name];
    fParent->fName = name;
    this->checkName(fParent);
    fParent->fFileName = fFileName;
    fParent->fType = Definition::Type::kFileType;
    fParent->fContentStart = fChar;
    fParent->fContentEnd = fEnd;
    // parse include file into tree
    while (fChar < fEnd) {
        if (!this->parseChar()) {
            return false;
        }
    }
    // parse tree and add named objects to maps
    fParent = &fIncludeMap[name];
    if (!this->parseObjects(fParent, nullptr)) {
        return false;
    }
    return true;
}

bool IncludeParser::parseMember(Definition* child, Definition* markupDef) {
    const char* typeStart = child->fChildren[0]->fContentStart;
    markupDef->fTokens.emplace_back(MarkType::kMember, typeStart, child->fContentStart,
        child->fLineCount, markupDef, '\0');
    Definition* markupChild = &markupDef->fTokens.back();
    TextParser nameParser(child);
    nameParser.skipToNonName();
    string nameStr = string(child->fContentStart, nameParser.fChar - child->fContentStart);
    IClassDefinition& classDef = fIClassMap[markupDef->fName];
    string uniqueName = this->uniqueName(classDef.fMethods, nameStr);
    markupChild->fName = uniqueName;
    this->checkName(markupChild);
    markupChild->fTerminator = markupChild->fContentEnd;
    if (!markupChild->fUndocumented) {
        classDef.fMembers[uniqueName] = markupChild;
    }
    if (child->fParentIndex >= 2) {
        auto comment = child->fParent->fTokens.begin();
        std::advance(comment, child->fParentIndex - 2);
        if (Definition::Type::kBracket == comment->fType
                && (Bracket::kSlashStar == comment->fBracket
                || Bracket::kSlashSlash == comment->fBracket)) {
            TextParser parser(&*comment);
            do {
                parser.skipToAlpha();
                if (parser.eof()) {
                    break;
                }
                const char* start = parser.fChar;
                const char* end = parser.trimmedBracketEnd('\n');
                if (Bracket::kSlashStar == comment->fBracket) {
                    const char* commentEnd = parser.strnstr("*/", end);
                    if (commentEnd) {
                        end = commentEnd;
                    }
                }
                markupDef->fTokens.emplace_back(MarkType::kComment, start, end, child->fLineCount,
                        markupDef, '\0');
                Definition* commentChild = &markupDef->fTokens.back();
                markupChild->fChildren.emplace_back(commentChild);
                parser.skipTo(end);
            } while (!parser.eof());
        }
    }
    return true;
}

bool IncludeParser::parseMethod(Definition* child, Definition* markupDef) {
    auto tokenIter = child->fParent->fTokens.begin();
    std::advance(tokenIter, child->fParentIndex);
    tokenIter = std::prev(tokenIter);
    const char* nameEnd = tokenIter->fContentEnd;
    bool addConst = false;
    auto operatorCheck = tokenIter;
    if ('[' == tokenIter->fStart[0] || '*' == tokenIter->fStart[0]) {
        operatorCheck = std::prev(tokenIter);
    }
    if (KeyWord::kOperator == operatorCheck->fKeyWord) {
        auto closeParen = std::next(tokenIter);
        SkASSERT(Definition::Type::kBracket == closeParen->fType &&
                '(' == closeParen->fContentStart[0]);
        nameEnd = closeParen->fContentEnd + 1;
        closeParen = std::next(closeParen);
        if (Definition::Type::kKeyWord == closeParen->fType &&
                KeyWord::kConst == closeParen->fKeyWord) {
            addConst = true;
        }
        tokenIter = operatorCheck;
    }
    string nameStr(tokenIter->fStart, nameEnd - tokenIter->fStart);
    if (addConst) {
        nameStr += " const";
    }
    while (tokenIter != child->fParent->fTokens.begin()) {
        auto testIter = std::prev(tokenIter);
        switch (testIter->fType) {
            case Definition::Type::kWord:
                if (testIter == child->fParent->fTokens.begin() &&
                        (KeyWord::kIfdef == child->fParent->fKeyWord ||
                        KeyWord::kIfndef == child->fParent->fKeyWord ||
                        KeyWord::kIf == child->fParent->fKeyWord)) {
                    std::next(tokenIter);
                    break;
                }
                goto keepGoing;
            case Definition::Type::kKeyWord: {
                KeyProperty keyProperty = kKeyWords[(int) testIter->fKeyWord].fProperty;
                if (KeyProperty::kNumber == keyProperty || KeyProperty::kModifier == keyProperty) {
                    goto keepGoing;
                }
            } break;
            case Definition::Type::kBracket:
                if (Bracket::kAngle == testIter->fBracket) {
                    goto keepGoing;
                }
                break;
            case Definition::Type::kPunctuation:
                if (Punctuation::kSemicolon == testIter->fPunctuation
                        || Punctuation::kLeftBrace == testIter->fPunctuation
                        || Punctuation::kColon == testIter->fPunctuation) {
                    break;
                }
            keepGoing:
                tokenIter = testIter;
                continue;
            default:
                break;
        }
        break;
    }
    tokenIter->fName = nameStr;     // simple token stream, OK if name is duplicate
    tokenIter->fMarkType = MarkType::kMethod;
    tokenIter->fPrivate = string::npos != nameStr.find("::")
            && KeyWord::kTemplate != child->fParent->fKeyWord;
    this->checkName(&*tokenIter);
    auto testIter = child->fParent->fTokens.begin();
    SkASSERT(child->fParentIndex > 0);
    std::advance(testIter, child->fParentIndex - 1);
    if (tokenIter->fParent && KeyWord::kIfdef == tokenIter->fParent->fKeyWord &&
            0 == tokenIter->fParentIndex) {
        tokenIter = std::next(tokenIter);
    }
    const char* start = tokenIter->fContentStart;
    const char* end = tokenIter->fContentEnd;
    const char kDebugCodeStr[] = "SkDEBUGCODE";
    const size_t kDebugCodeLen = sizeof(kDebugCodeStr) - 1;
    if (end - start == kDebugCodeLen && !strncmp(start, kDebugCodeStr, kDebugCodeLen)) {
        std::advance(testIter, 1);
        start = testIter->fContentStart + 1;
        end = testIter->fContentEnd - 1;
    } else {
        end = testIter->fContentEnd;
        do {
            std::advance(testIter, 1);
            if (testIter == child->fParent->fTokens.end()) {
                break;
            }
            switch (testIter->fType) {
                case Definition::Type::kPunctuation:
                    SkASSERT(Punctuation::kSemicolon == testIter->fPunctuation
                            || Punctuation::kLeftBrace == testIter->fPunctuation
                            || Punctuation::kColon == testIter->fPunctuation);
                    end = testIter->fStart;
                    break;
                case Definition::Type::kKeyWord: {
                    KeyProperty keyProperty = kKeyWords[(int) testIter->fKeyWord].fProperty;
                    if (KeyProperty::kNumber == keyProperty || KeyProperty::kModifier == keyProperty) {
                        continue;
                    }
                    } break;
                default:
                    continue;
            }
            break;
        } while (true);
    }
    while (end > start && ' ' >= end[-1]) {
        --end;
    }
    if (!markupDef) {
        auto parentIter = child->fParent->fTokens.begin();
        SkASSERT(child->fParentIndex > 0);
        std::advance(parentIter, child->fParentIndex - 1);
        Definition* methodName = &*parentIter;
        TextParser nameParser(methodName);
        if (nameParser.skipToEndBracket(':') && nameParser.startsWith("::")) {
            return true;  // expect this is inline class definition outside of class
        }
        fGlobals.emplace_back(MarkType::kMethod, start, end, tokenIter->fLineCount,
                fParent, '\0');
        Definition* globalMarkupChild = &fGlobals.back();
        string globalUniqueName = this->uniqueName(fIFunctionMap, nameStr);
        globalMarkupChild->fName = globalUniqueName;
        if (!this->findComments(*child, globalMarkupChild)) {
            return false;
        }
        if (globalMarkupChild->fUndocumented) {
            child->fUndocumented = true;
        } else {
            fIFunctionMap[globalUniqueName] = globalMarkupChild;
        }
        return true;
    }
    markupDef->fTokens.emplace_back(MarkType::kMethod, start, end, tokenIter->fLineCount,
            markupDef, '\0');
    Definition* markupChild = &markupDef->fTokens.back();
    {
        auto mapIter = fIClassMap.find(markupDef->fName);
        SkASSERT(fIClassMap.end() != mapIter);
        IClassDefinition& classDef = mapIter->second;
        SkASSERT(classDef.fStart);
        string uniqueName = this->uniqueName(classDef.fMethods, nameStr);
        markupChild->fName = uniqueName;
        if (!this->findComments(*child, markupChild)) {
            return false;
        }
        if (markupChild->fUndocumented) {
            tokenIter->fUndocumented = true;
        } else {
            classDef.fMethods[uniqueName] = markupChild;
        }
    }
    return true;
}

bool IncludeParser::parseObjects(Definition* parent, Definition* markupDef) {
    fPriorObject = nullptr;
    for (auto child : parent->fChildren) {
        if (!this->parseObject(child, markupDef)) {
            return false;
        }
        fPriorObject = child;
    }
    return true;
}

bool IncludeParser::parseObject(Definition* child, Definition* markupDef) {
    // set up for error reporting
    fLine = fChar = child->fStart;
    fEnd = child->fContentEnd;
    // todo: put original line number in child as well
    switch (child->fType) {
        case Definition::Type::kKeyWord:
            switch (child->fKeyWord) {
                case KeyWord::kClass:
                    if (!this->parseClass(child, IsStruct::kNo)) {
                        return false;
                    }
                    break;
                case KeyWord::kStatic:
                case KeyWord::kConst:
                case KeyWord::kConstExpr:
                    if (!this->parseConst(child, markupDef)) {
                        return child->reportError<bool>("failed to parse const or constexpr");
                    }
                    break;
                case KeyWord::kEnum:
                    if (!this->parseEnum(child, markupDef)) {
                        return child->reportError<bool>("failed to parse enum");
                    }
                    break;
                case KeyWord::kStruct:
                    if (!this->parseClass(child, IsStruct::kYes)) {
                        return child->reportError<bool>("failed to parse struct");
                    }
                    break;
                case KeyWord::kTemplate:
                    if (!this->parseTemplate(child, markupDef)) {
                        return child->reportError<bool>("failed to parse template");
                    }
                    break;
                case KeyWord::kTypedef:
                    if (!this->parseTypedef(child, markupDef)) {
                        return child->reportError<bool>("failed to parse typedef");
                    }
                    break;
                case KeyWord::kUnion:
                    if (!this->parseUnion()) {
                        return child->reportError<bool>("failed to parse union");
                    }
                    break;
                case KeyWord::kUsing:
                    if (!this->parseUsing()) {
                        return child->reportError<bool>("failed to parse using");
                    }
                    break;
                default:
                    return child->reportError<bool>("unhandled keyword");
            }
            break;
        case Definition::Type::kBracket:
            switch (child->fBracket) {
                case Bracket::kParen:
                    {
                        auto tokenIter = child->fParent->fTokens.begin();
                        std::advance(tokenIter, child->fParentIndex);
                        tokenIter = std::prev(tokenIter);
                        TextParser previousToken(&*tokenIter);
                        if (this->isMember(*tokenIter)) {
                            break;
                        }
                        if (Bracket::kPound == child->fParent->fBracket &&
                                KeyWord::kIf == child->fParent->fKeyWord) {
                            // TODO: this will skip methods named defined() -- for the
                            // moment there aren't any
                            if (previousToken.startsWith("defined")) {
                                break;
                            }
                        }
                        if (previousToken.startsWith("sizeof") && 6 == previousToken.lineLength()) {
                            break;
                        }
                    }
                    if (fPriorObject && MarkType::kConst == fPriorObject->fMarkType) {
                        break;
                    }
                    if (!this->parseMethod(child, markupDef)) {
                        return child->reportError<bool>("failed to parse method");
                    }
                break;
                case Bracket::kSlashSlash:
                case Bracket::kSlashStar:
                    // comments are picked up by parsing objects first
                    break;
                case Bracket::kPound:
                    // special-case the #xxx xxx_DEFINED entries
                    switch (child->fKeyWord) {
                        case KeyWord::kIf:
                        case KeyWord::kIfndef:
                        case KeyWord::kIfdef:
                            if (child->boilerplateIfDef()) {
                                if (!this->parseObjects(child, markupDef)) {
                                    return false;
                                }
                                break;
                            }
                            goto preproError;
                        case KeyWord::kDefine:
                            if (this->parseDefine(child, markupDef)) {
                                break;
                            }
                            goto preproError;
                        case KeyWord::kEndif:
                            if (child->boilerplateEndIf()) {
                                break;
                            }
                        case KeyWord::kError:
                        case KeyWord::kInclude:
                            // ignored for now
                            break;
                        case KeyWord::kElse:
                            if (!this->parseObjects(child, markupDef)) {
                                return false;
                            }
                            break;
                        case KeyWord::kElif:
                            // todo: handle these
                            break;
                        default:
                        preproError:
                            return child->reportError<bool>("unhandled preprocessor");
                    }
                    break;
                case Bracket::kAngle:
                    // pick up templated function pieces when method is found
                    break;
                case Bracket::kDebugCode:
                    if (!this->parseObjects(child, markupDef)) {
                        return false;
                    }
                    break;
                case Bracket::kSquare: {
                    // check to see if parent is operator, the only case we handle so far
                    auto prev = child->fParent->fTokens.begin();
                    std::advance(prev, child->fParentIndex - 1);
                    if (KeyWord::kOperator != prev->fKeyWord) {
                        return child->reportError<bool>("expected operator overload");
                    }
                    } break;
                default:
                    return child->reportError<bool>("unhandled bracket");
            }
            break;
        case Definition::Type::kWord:
            if (MarkType::kMember != child->fMarkType) {
                return child->reportError<bool>("unhandled word type");
            }
            if (!this->parseMember(child, markupDef)) {
                return child->reportError<bool>("unparsable member");
            }
            break;
        default:
            return child->reportError<bool>("unhandled type");
            break;
    }
    return true;
}

bool IncludeParser::parseTemplate(Definition* child, Definition* markupDef) {
    return this->parseObjects(child, markupDef);
}

bool IncludeParser::parseTypedef(Definition* child, Definition* markupDef) {
    TextParser typedefParser(child);
    typedefParser.skipExact("typedef");
    typedefParser.skipWhiteSpace();
    string nameStr = typedefParser.typedefName();
    if (!markupDef) {
        fGlobals.emplace_back(MarkType::kTypedef, child->fContentStart, child->fContentEnd,
                child->fLineCount, fParent, '\0');
        Definition* globalMarkupChild = &fGlobals.back();
        string globalUniqueName = this->uniqueName(fITypedefMap, nameStr);
        globalMarkupChild->fName = globalUniqueName;
        if (!this->findComments(*child, globalMarkupChild)) {
            return false;
        }
        if (globalMarkupChild->fUndocumented) {
            child->fUndocumented = true;
        } else {
            fITypedefMap[globalUniqueName] = globalMarkupChild;
        }
        child->fName = nameStr;
        return true;
    }
    markupDef->fTokens.emplace_back(MarkType::kTypedef, child->fContentStart, child->fContentEnd,
        child->fLineCount, markupDef, '\0');
    Definition* markupChild = &markupDef->fTokens.back();
    markupChild->fName = nameStr;
    this->checkName(markupChild);
    markupChild->fTerminator = markupChild->fContentEnd;
    IClassDefinition& classDef = fIClassMap[markupDef->fName];
    classDef.fTypedefs[nameStr] = markupChild;
    child->fName = markupDef->fName + "::" + nameStr;
    this->checkName(child);
    fITypedefMap[child->fName] = markupChild;
    return true;
}

bool IncludeParser::parseUnion() {
    // incomplete
    return true;
}

bool IncludeParser::parseUsing() {
    // incomplete
    return true;
}

bool IncludeParser::parseChar() {
    char test = *fChar;
    if ('\\' == fPrev) {
        if ('\n' == test) {
//            ++fLineCount;
            fLine = fChar + 1;
        }
        goto done;
    }
    switch (test) {
        case '\n':
//            ++fLineCount;
            fLine = fChar + 1;
            if (fInChar) {
                return reportError<bool>("malformed char");
            }
            if (fInString) {
                return reportError<bool>("malformed string");
            }
            if (!this->checkForWord()) {
                return false;
            }
            if (Bracket::kPound == this->topBracket()) {
                KeyWord keyWord = fParent->fKeyWord;
                if (KeyWord::kNone == keyWord) {
                    return this->reportError<bool>("unhandled preprocessor directive");
                }
                if (fInDefine) {
                    SkASSERT(KeyWord::kDefine == keyWord);
                    fInDefine = false;
                }
                if (KeyWord::kInclude == keyWord || KeyWord::kDefine == keyWord || KeyWord::kError == keyWord) {
                    this->popBracket();
                }
                if (fInBrace) {
                    SkASSERT(KeyWord::kDefine == fInBrace->fKeyWord);
                    fInBrace = nullptr;
                }
            } else if (Bracket::kSlashSlash == this->topBracket()) {
                this->popBracket();
            }
            break;
        case '*':
            if (!fInCharCommentString && '/' == fPrev) {
                this->pushBracket(Bracket::kSlashStar);
            }
            if (!this->checkForWord()) {
                return false;
            }
            if (!fInCharCommentString) {
                this->addPunctuation(Punctuation::kAsterisk);
            }
            break;
        case '/':
            if ('*' == fPrev) {
                if (!fInCharCommentString) {
                    return reportError<bool>("malformed closing comment");
                }
                if (Bracket::kSlashStar == this->topBracket()) {
                    TextParserSave save(this);
                    this->next();  // include close in bracket
                    this->popBracket();
                    save.restore(); // put things back so nothing is skipped
                }
                break;
            }
            if (!fInCharCommentString && '/' == fPrev) {
                this->pushBracket(Bracket::kSlashSlash);
                break;
            }
            if (!this->checkForWord()) {
                return false;
            }
            break;
        case '\'':
            if (Bracket::kChar == this->topBracket()) {
                this->popBracket();
            } else if (!fInComment && !fInString) {
                if (fIncludeWord) {
                    return this->reportError<bool>("word then single-quote");
                }
                this->pushBracket(Bracket::kChar);
            }
            break;
        case '\"':
            if (Bracket::kString == this->topBracket()) {
                this->popBracket();
            } else if (!fInComment && !fInChar) {
                if (fIncludeWord) {
                    return this->reportError<bool>("word then double-quote");
                }
                this->pushBracket(Bracket::kString);
            }
            break;
        case '(':
            if (fIncludeWord && fChar - fIncludeWord >= 10 &&
                    !strncmp("SkDEBUGCODE", fIncludeWord, 10)) {
                this->pushBracket(Bracket::kDebugCode);
                break;
            }
        case ':':
        case '[':
        case '{': {
            if (fInCharCommentString) {
                break;
            }
            if (fInDefine && fInBrace) {
                break;
            }
            if (':' == test && (fInBrace || ':' == fChar[-1] || ':' == fChar[1])) {
                break;
            }
            if (fConstExpr) {
                fConstExpr->fContentEnd = fParent->fTokens.back().fContentEnd;
                fConstExpr = nullptr;
            }
            if (!fInBrace) {
                if (!this->checkForWord()) {
                    return false;
                }
                if (':' == test && !fInFunction) {
                    break;
                }
                if ('{' == test) {
                    this->addPunctuation(Punctuation::kLeftBrace);
                } else if (':' == test) {
                    this->addPunctuation(Punctuation::kColon);
                }
            }
            if (fInBrace && '{' == test && Definition::Type::kBracket == fInBrace->fType
                    && Bracket::kColon == fInBrace->fBracket) {
                Definition* braceParent = fParent->fParent;
                braceParent->fChildren.pop_back();
                braceParent->fTokens.pop_back();
                fParent = braceParent;
                fInBrace = nullptr;
            }
            this->pushBracket(
                    '(' == test ? Bracket::kParen :
                    '[' == test ? Bracket::kSquare :
                    '{' == test ? Bracket::kBrace :
                                  Bracket::kColon);
            if (!fInBrace
                    && ('{' == test || (':' == test && ' ' >= fChar[1]))
                    && fInFunction) {
                fInBrace = fParent;
            }
            } break;
        case '<':
            if (fInCharCommentString || fInBrace) {
                break;
            }
            if (!this->checkForWord()) {
                return false;
            }
            if (fInEnum) {
                break;
            }
            this->pushBracket(Bracket::kAngle);
            // this angle bracket may be an operator or may be a bracket
            // wait for balancing close angle, if any, to decide
            break;
        case ')':
        case ']':
        case '}': {
            if (fInCharCommentString) {
                break;
            }
            if (fInDefine && fInBrace) {
                break;
            }
            if (!fInBrace) {
                if (!this->checkForWord()) {
                    return false;
                }
            }
            bool popBraceParent = fInBrace == fParent;
            Bracket match = ')' == test ? Bracket::kParen :
                    ']' == test ? Bracket::kSquare : Bracket::kBrace;
            if (match == this->topBracket()) {
                this->popBracket();
                if (!fInFunction) {
                    fInFunction = ')' == test && !this->inAlignAs();
                } else {
                    fInFunction = '}' != test;
                }
            } else if (')' == test && Bracket::kDebugCode == this->topBracket()) {
                this->popBracket();
            } else if (Bracket::kAngle == this->topBracket()
                    && match == this->grandParentBracket()) {
                this->popBracket();
                this->popBracket();
            } else {
                return reportError<bool>("malformed close bracket");
            }
            if (popBraceParent) {
                Definition* braceParent = fInBrace->fParent;
                braceParent->fChildren.pop_back();
                braceParent->fTokens.pop_back();
                fInBrace = nullptr;
            }
            } break;
        case '>':
            if (fInCharCommentString || fInBrace) {
                break;
            }
            if (!this->checkForWord()) {
                return false;
            }
            if (fInEnum) {
                break;
            }
            if (Bracket::kPound == this->topBracket()) {
                break;
            }
            if (Bracket::kAngle == this->topBracket()) {
                // looks like angle pair are braces, not operators
                this->popBracket();
            } else {
                return reportError<bool>("malformed close angle bracket");
            }
            break;
        case '#': {
            if (fInCharCommentString || fInBrace) {
                break;
            }
            SkASSERT(!fIncludeWord);  // don't expect this, curious if it is triggered
            this->pushBracket(Bracket::kPound);
            break;
        }
        case ' ':
            if (fInDefine && !fInBrace && Bracket::kPound == this->topBracket()) {
                SkASSERT(KeyWord::kDefine == fParent->fKeyWord);
                fInBrace = fParent;
                // delimiting brackets are space ... unescaped-linefeed
            }
        case '&':
        case ',':
        case '+':
        case '-':
        case '!':
            if (fInCharCommentString || fInBrace) {
                break;
            }
            if (!this->checkForWord()) {
                return false;
            }
            break;
        case '=':
            if (fInCharCommentString || fInBrace) {
                break;
            }
            if (!this->checkForWord()) {
                return false;
            }
            if (!fParent->fTokens.size()) {
                break;
            }
            {
                const Definition& lastToken = fParent->fTokens.back();
                if (lastToken.fType != Definition::Type::kWord) {
                    break;
                }
                string name(lastToken.fContentStart, lastToken.length());
                if ("SK_" != name.substr(0, 3) && 'k' != name[0]) {
                    break;
                }
                // find token on start of line
                auto lineIter = fParent->fTokens.end();
                do {
                    if (fParent->fTokens.begin() == lineIter) {
                        break;
                    }
                    --lineIter;
                } while (lineIter->fContentStart > fLine);
                if (lineIter->fContentStart < fLine && fParent->fTokens.end() != lineIter) {
                    ++lineIter;
                }
                Definition* lineStart = &*lineIter;
                // walk tokens looking for [template <typename T>] [static] [const | constexpr]
                bool sawConst = false;
                bool sawStatic = false;
                bool sawTemplate = false;
                bool sawType = false;
                while (&lastToken != &*lineIter) {
                    if (KeyWord::kTemplate == lineIter->fKeyWord) {
                        if (sawConst || sawStatic || sawTemplate) {
                            sawConst = false;
                            break;
                        }
                        if (&lastToken == &*++lineIter) {
                            break;
                        }
                        if (KeyWord::kTypename != lineIter->fKeyWord) {
                            break;
                        }
                        if (&lastToken == &*++lineIter) {
                            break;
                        }
                        if (Definition::Type::kWord != lineIter->fType) {
                            break;
                        }
                        sawTemplate = true;
                    } else if (KeyWord::kStatic == lineIter->fKeyWord) {
                        if (sawConst || sawStatic) {
                            sawConst = false;
                            break;
                        }
                        sawStatic = true;
                    } else if (KeyWord::kConst == lineIter->fKeyWord
                            || KeyWord::kConstExpr == lineIter->fKeyWord) {
                        if (sawConst) {
                            sawConst = false;
                            break;
                        }
                        sawConst = true;
                    } else {
                        if (sawType) {
                            sawType = false;
                            break;
                        }
                        if (Definition::Type::kKeyWord == lineIter->fType
                                && KeyProperty::kNumber
                                == kKeyWords[(int) lineIter->fKeyWord].fProperty) {
                            sawType = true;
                        } else if (Definition::Type::kWord == lineIter->fType) {
                            string typeName(lineIter->fContentStart, lineIter->length());
                            if ("Sk" != name.substr(0, 2)) {
                                sawType = true;
                            }
                        }
                    }
                    ++lineIter;
                }
                if (sawType && sawConst) {
                    // if found, name first
                    lineStart->fName = name;
                    lineStart->fMarkType = MarkType::kConst;
                    this->checkName(lineStart);
                    fParent->fChildren.emplace_back(lineStart);
                    fConstExpr = lineStart;
                }
            }
            break;
        case ';':
            if (fInCharCommentString || fInBrace) {
                break;
            }
            if (!this->checkForWord()) {
                return false;
            }
            if (fConstExpr) {
                fConstExpr->fContentEnd = fParent->fTokens.back().fContentEnd;
                fConstExpr = nullptr;
            }
            if (Definition::Type::kKeyWord == fParent->fType
                    && KeyProperty::kObject == (kKeyWords[(int) fParent->fKeyWord].fProperty)) {
                bool parentIsClass = KeyWord::kClass == fParent->fKeyWord;
                if (parentIsClass && fParent->fParent &&
                        KeyWord::kEnum == fParent->fParent->fKeyWord) {
                    this->popObject();
                }
                if (KeyWord::kEnum == fParent->fKeyWord) {
                    fInEnum = false;
                }
                parentIsClass |= KeyWord::kStruct == fParent->fKeyWord;
                this->popObject();
                if (parentIsClass && fParent && KeyWord::kTemplate == fParent->fKeyWord) {
                    this->popObject();
                }
                fPriorEnum = nullptr;
            } else if (Definition::Type::kBracket == fParent->fType
                    && fParent->fParent && Definition::Type::kKeyWord == fParent->fParent->fType
                    && KeyWord::kStruct == fParent->fParent->fKeyWord) {
                list<Definition>::iterator baseIter = fParent->fTokens.end();
                list<Definition>::iterator namedIter  = fParent->fTokens.end();
                for (auto tokenIter = fParent->fTokens.end();
                        fParent->fTokens.begin() != tokenIter; ) {
                    --tokenIter;
                    if (tokenIter->fLineCount == fLineCount) {
                        if (this->isMember(*tokenIter)) {
                            if (namedIter != fParent->fTokens.end()) {
                                return reportError<bool>("found two named member tokens");
                            }
                            namedIter = tokenIter;
                        }
                        baseIter = tokenIter;
                    } else {
                        break;
                    }
                }
                // FIXME: if a member definition spans multiple lines, this won't work
                if (namedIter != fParent->fTokens.end()) {
                    if (baseIter == namedIter) {
                        return this->reportError<bool>("expected type before named token");
                    }
                    Definition* member = &*namedIter;
                    member->fMarkType = MarkType::kMember;
                    if (!member->fTerminator) {
                        member->fTerminator = member->fContentEnd;
                    }
                    fParent->fChildren.push_back(member);
                    for (auto nameType = baseIter; nameType != namedIter; ++nameType) {
                        member->fChildren.push_back(&*nameType);
                    }
                }
                fPriorEnum = nullptr;
            } else if (fParent->fChildren.size() > 0) {
                auto lastIter = fParent->fChildren.end();
                Definition* priorEnum = fPriorEnum;
                fPriorEnum = nullptr;
                if (!priorEnum) {
                    while (fParent->fChildren.begin() != lastIter) {
                        std::advance(lastIter, -1);
                        priorEnum = *lastIter;
                        if (Definition::Type::kBracket != priorEnum->fType ||
                                (Bracket::kSlashSlash != priorEnum->fBracket
                                && Bracket::kSlashStar != priorEnum->fBracket)) {
                            break;
                        }
                    }
                    fPriorIndex = priorEnum->fParentIndex;
                }
                if (Definition::Type::kKeyWord == priorEnum->fType
                        && KeyWord::kEnum == priorEnum->fKeyWord) {
                    auto tokenWalker = fParent->fTokens.begin();
                    std::advance(tokenWalker, fPriorIndex);
                    while (tokenWalker != fParent->fTokens.end()) {
                        std::advance(tokenWalker, 1);
                        ++fPriorIndex;
                        if (Punctuation::kSemicolon == tokenWalker->fPunctuation) {
                            break;
                        }
                    }
                    while (tokenWalker != fParent->fTokens.end()) {
                        std::advance(tokenWalker, 1);
                        const Definition* test = &*tokenWalker;
                        if (Definition::Type::kBracket != test->fType ||
                                (Bracket::kSlashSlash != test->fBracket
                                && Bracket::kSlashStar != test->fBracket)) {
                            break;
                        }
                    }
                    auto saveTokenWalker = tokenWalker;
                    Definition* start = &*tokenWalker;
                    bool foundExpected = true;
                    for (KeyWord expected : {KeyWord::kStatic, KeyWord::kConstExpr, KeyWord::kInt}){
                        const Definition* test = &*tokenWalker;
                        if (expected != test->fKeyWord) {
                            foundExpected = false;
                            break;
                        }
                        if (tokenWalker == fParent->fTokens.end()) {
                            break;
                        }
                        std::advance(tokenWalker, 1);
                    }
                    if (!foundExpected) {
                        foundExpected = true;
                        tokenWalker = saveTokenWalker;
                        for (KeyWord expected : {KeyWord::kStatic, KeyWord::kConst, KeyWord::kNone}){
                            const Definition* test = &*tokenWalker;
                            if (expected != test->fKeyWord) {
                                foundExpected = false;
                                break;
                            }
                            if (tokenWalker == fParent->fTokens.end()) {
                                break;
                            }
                            if (KeyWord::kNone != expected) {
                                std::advance(tokenWalker, 1);
                            }
                        }
                        if (foundExpected) {
                            auto nameToken = priorEnum->fTokens.begin();
                            string enumName = string(nameToken->fContentStart,
                                    nameToken->fContentEnd - nameToken->fContentStart);
                            const Definition* test = &*tokenWalker;
                            string constType = string(test->fContentStart,
                                    test->fContentEnd - test->fContentStart);
                            if (enumName != constType) {
                                foundExpected = false;
                            } else {
                                std::advance(tokenWalker, 1);
                            }
                        }
                    }
                    if (foundExpected && tokenWalker != fParent->fTokens.end()) {
                        const char* nameStart = tokenWalker->fStart;
                        std::advance(tokenWalker, 1);
                        if (tokenWalker != fParent->fTokens.end()) {
                            TextParser tp(fFileName, nameStart, tokenWalker->fStart, fLineCount);
                            tp.skipToNonName();
                            start->fName = string(nameStart, tp.fChar - nameStart);
                            this->checkName(start);
                            start->fContentEnd = fChar;
                            priorEnum->fChildren.emplace_back(start);
                            fPriorEnum = priorEnum;
                        }
                    }
                }
            }
            this->addPunctuation(Punctuation::kSemicolon);
            fInFunction = false;
            break;
        case '~':
            if (fInEnum) {
                break;
            }
        case '0': case '1': case '2': case '3': case '4':
        case '5': case '6': case '7': case '8': case '9':
            // TODO: don't want to parse numbers, but do need to track for enum defs
        //    break;
        case 'A': case 'B': case 'C': case 'D': case 'E':
        case 'F': case 'G': case 'H': case 'I': case 'J':
        case 'K': case 'L': case 'M': case 'N': case 'O':
        case 'P': case 'Q': case 'R': case 'S': case 'T':
        case 'U': case 'V': case 'W': case 'X': case 'Y':
        case 'Z': case '_':
        case 'a': case 'b': case 'c': case 'd': case 'e':
        case 'f': case 'g': case 'h': case 'i': case 'j':
        case 'k': case 'l': case 'm': case 'n': case 'o':
        case 'p': case 'q': case 'r': case 's': case 't':
        case 'u': case 'v': case 'w': case 'x': case 'y':
        case 'z':
            if (fInCharCommentString || fInBrace) {
                break;
            }
            if (!fIncludeWord) {
                fIncludeWord = fChar;
            }
            break;
    }
done:
    fPrev = test;
    this->next();
    return true;
}

void IncludeParser::validate() const {
    IncludeParser::ValidateKeyWords();
}

bool IncludeParser::references(const SkString& file) const {
    // if includes weren't passed one at a time, assume all references are valid
    if (fIncludeMap.empty()) {
        return true;
    }
    SkASSERT(file.endsWith(".bmh") );
    string root(file.c_str(), file.size() - 4);
    string kReference("_Reference");
    if (string::npos != root.find(kReference)) {
        root = root.substr(0, root.length() - kReference.length());
    }
    if (fIClassMap.end() != fIClassMap.find(root)) {
        return true;
    }
    if (fIStructMap.end() != fIStructMap.find(root)) {
        return true;
    }
    if (fIEnumMap.end() != fIEnumMap.find(root)) {
        return true;
    }
    if (fITypedefMap.end() != fITypedefMap.find(root)) {
        return true;
    }
    if (fIFunctionMap.end() != fIFunctionMap.find(root)) {
        return true;
    }
    return false;
}

void IncludeParser::RemoveFile(const char* docs, const char* includes) {
    if (!sk_isdir(includes)) {
        IncludeParser::RemoveOneFile(docs, includes);
    } else {
        SkOSFile::Iter it(includes, ".h");
        for (SkString file; it.next(&file); ) {
            SkString p = SkOSPath::Join(includes, file.c_str());
            const char* hunk = p.c_str();
            if (!SkStrEndsWith(hunk, ".h")) {
                continue;
            }
            IncludeParser::RemoveOneFile(docs, hunk);
        }
    }
}

void IncludeParser::RemoveOneFile(const char* docs, const char* includesFile) {
    const char* lastForward = strrchr(includesFile, '/');
    const char* lastBackward = strrchr(includesFile, '\\');
    const char* last = lastForward > lastBackward ? lastForward : lastBackward;
    if (!last) {
        last = includesFile;
    } else {
        last += 1;
    }
    SkString baseName(last);
    SkASSERT(baseName.endsWith(".h"));
    baseName.remove(baseName.size() - 2, 2);
    baseName.append("_Reference.bmh");
    SkString fullName = docs ? SkOSPath::Join(docs, baseName.c_str()) : baseName;
    remove(fullName.c_str());
}

static const char kMethodMissingStr[] =
    "If the method requires documentation, add to "
    "%s at minimum:\n"  // path to bmh file
    "\n"
    "#Method %s\n" // method declaration less implementation details
    "#In  SomeSubtopicName\n"
    "#Line # add a one line description here ##\n"
    "#Populate\n"
    "#NoExample\n"
    "// or better yet, use #Example and put C++ code here\n"
    "##\n"
    "#SeeAlso optional related symbols\n"
    "#Method ##\n"
    "\n"
    "Add to %s, at minimum:\n"  // path to include
    "\n"
    "/** (description) Starts with present tense action verb\n"
    "    and end with a period.\n"
    "%s"   // @param, @return if needed go here
    "*/\n"
    "%s ...\n" // method declaration
    "\n"
    "If the method does not require documentation,\n"
    "add \"private\" or \"experimental\", as in:\n"
    "\n"
    "/** Experimental, do not use. And so on...\n"
    "*/\n"
    "%s ...\n" // method declaration
    "\n"
    ;

// bDef does not have #Populate
static const char kMethodDiffersNoPopStr[] =
    "In %s:\n"              // path to bmh file
    "#Method %s\n"          // method declaration less implementation details
    "does not match doxygen comment of:\n"
    "%s.\n"                 // method declaration
    "\n"
    ;

static const char kMethodDiffersStr[] =
    "In %s:\n"                        // path to include
    "%s\n"                            // method declaration
    "does not match doxygen comment.\n"
    "\n"
    ;

void IncludeParser::suggestFix(Suggest suggest, const Definition& iDef,
        const RootDefinition* root, const Definition* bDef) {
    string methodNameStr(iDef.fContentStart, iDef.length());
    const char* methodName = methodNameStr.c_str();
    TextParser lessImplParser(&iDef);
    if (lessImplParser.skipExact("static")) {
        lessImplParser.skipWhiteSpace();
    }
    // TODO : handle debug wrapper
    /* bool inDebugWrapper = */ Definition::SkipImplementationWords(lessImplParser);
    string lessImplStr(lessImplParser.fChar, lessImplParser.fEnd - lessImplParser.fChar);
    const char* methodNameLessImpl = lessImplStr.c_str();
    // return result, if any is substr from 0 to location of iDef.fName
    size_t namePos = methodNameStr.find(iDef.fName);
    SkASSERT(string::npos != namePos);
    size_t funcEnd = namePos;
    while (funcEnd > 0 && ' ' >= methodNameStr[funcEnd - 1]) {
        funcEnd -= 1;
    }
    string funcRet = methodNameStr.substr(0, funcEnd);
// parameters, if any, are delimited by () and separate by ,
    TextParser parser(&iDef);
    parser.fChar += namePos + iDef.fName.length();
    const char* start = parser.fChar;
    vector<string> paramStrs;
    if ('(' == start[0]) {
        parser.skipToBalancedEndBracket('(', ')');
        TextParser params(&iDef);
        params.fChar = start + 1;
        params.fEnd = parser.fChar;
        while (!params.eof()) {
            const char* paramEnd = params.anyOf("=,)");
            const char* paramStart = paramEnd;
            while (paramStart > params.fChar && ' ' >= paramStart[-1]) {
                paramStart -= 1;
            }
            while (paramStart > params.fChar && (isalnum(paramStart[-1])
                    || '_' == paramStart[-1])) {
                paramStart -= 1;
            }
            string param(paramStart, paramEnd - paramStart);
            paramStrs.push_back(param);
            params.fChar = params.anyOf(",)") + 1;
        }
    }
    string bmhFile = root ? root->fFileName : bDef ? bDef->fFileName : "a *.bmh file";
    bool hasFuncReturn = "" != funcRet && "void" != funcRet;
    switch(suggest) {
        case Suggest::kMethodMissing: {
            // if include @param, @return are missing, request them as well
            string paramDox;
            bool firstParam = true;
            for (auto paramStr : paramStrs) {
                if (firstParam) {
                    paramDox += "\n";
                    firstParam = false;
                }
                paramDox += "    @param " + paramStr + "  descriptive phrase\n";
            }
            if (hasFuncReturn) {
                paramDox += "\n";
                paramDox += "    @return descriptive phrase\n";
            }
            SkDebugf(kMethodMissingStr, bmhFile.c_str(), methodNameLessImpl, iDef.fFileName.c_str(),
                    paramDox.c_str(), methodName, methodName);
            } break;
        case Suggest::kMethodDiffers: {
            bool hasPop = std::any_of(bDef->fChildren.begin(), bDef->fChildren.end(),
                    [](Definition* def) { return MarkType::kPopulate == def->fMarkType; });
            if (!hasPop) {
                SkDebugf(kMethodDiffersNoPopStr, bmhFile.c_str(), methodNameLessImpl, methodName);
            }
            SkDebugf(kMethodDiffersStr, iDef.fFileName.c_str(), methodName);
            } break;
        default:
            SkASSERT(0);
    }
}

Bracket IncludeParser::topBracket() const {
    Definition* parent = this->parentBracket(fParent);
    return parent ? parent->fBracket : Bracket::kNone;
}
