/*
 * 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) {
    i.skipWhiteSpace(&fCheck.fIndent, &fCheck.fWriteReturn);
    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, 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, MarkType markType) {
    TextParser i(&iDef);
    fElided = Elided::kNo;
    const char* before = iDef.fContentStart;
    while (' ' == *--before)
        ;
    int startIndent = iDef.fContentStart - before - 1;
    return writeCodeBlock(i, markType, startIndent);
}

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 elidedTemplate = Elided::kYes == fElided && !strncmp(i.fStart, "template ", 9);
    bool elidedTClass = elidedTemplate && MarkType::kClass == markType;
    if (fCheck.fWriteReturn || elidedTClass) {
        this->codeBlockAppend(result, '\n');
    }
    if ((MarkType::kFunction != markType && lastIndent > startIndent) || elidedTClass) {
        this->codeBlockAppend(result, '}');
    }
    this->codeBlockAppend(result, ';');
    if (MarkType::kFunction != markType || elidedTemplate) {
        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() {
    for (auto& classMapper : fIClassMap) {
        classMapper.second.fCode = this->writeCodeBlock(classMapper.second, MarkType::kClass);
    }
    for (auto& enumMapper : fIEnumMap) {
        enumMapper.second->fCode = this->writeCodeBlock(*enumMapper.second,
                enumMapper.second->fMarkType);
    }
    for (auto& typedefMapper : fITypedefMap) {
        typedefMapper.second->fCode = this->writeCodeBlock(*typedefMapper.second,
                typedefMapper.second->fMarkType);
    }
    for (auto& defineMapper : fIDefineMap) {
        defineMapper.second->fCode = this->writeCodeBlock(*defineMapper.second,
                defineMapper.second->fMarkType);
    }
}

#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;
    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;
    for (auto& token : tokens) {
        if (Definition::Type::kMark == token.fType && MarkType::kComment == token.fMarkType) {
            continue;
        }
        if (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:
                this->dumpMethod(token, classDef.fName);
            break;
            case MarkType::kMember:
                this->dumpMember(token);
                continue;
            break;
            case MarkType::kTypedef:
                this->dumpTypedef(token, classDef.fName);
            break;
            default:
                SkASSERT(0);
        }
        this->dumpCommonTail(token);
    }
}
void IncludeParser::dumpComment(const Definition& token) {
    fLineCount = token.fLineCount;
    fChar = fLine = token.fContentStart;
    fEnd = token.fContentEnd;
    bool sawParam = false;
    bool multiline = false;
    bool sawReturn = false;
    bool sawComment = false;
    bool methodHasReturn = false;
    vector<string> methodParams;
    vector<string> foundParams;
    Definition methodName;
    TextParser methodParser(token.fFileName, token.fContentStart, token.fContentEnd,
            token.fLineCount);
    bool debugCode = methodParser.skipExact("SkDEBUGCODE(");
    if (MarkType::kMethod == token.fMarkType) {
        methodName.fName = debugCode ? token.fName : string(token.fContentStart,
                (int) (token.fContentEnd - token.fContentStart));
        methodHasReturn = !methodParser.startsWith("void ")
                && !methodParser.startsWith("static void ")
                && !methodParser.strnchr('~', methodParser.fEnd);
        const char* paren = methodParser.strnchr('(', methodParser.fEnd);
        const char* nextEnd = paren;
        do {
            string paramName;
            methodParser.fChar = nextEnd + 1;
            methodParser.skipSpace();
            if (!methodName.nextMethodParam(&methodParser, &nextEnd, &paramName)) {
                continue;
            }
            methodParams.push_back(paramName);
        } while (')' != nextEnd[0]);
    }
    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.fContentStart[0]) {
                TextParser parser(&child);
                do {
                    parser.next();
                    if (parser.startsWith("param ")) {
                        parser.skipWord("param");
                        const char* parmStart = parser.fChar;
                        parser.skipToSpace();
                        string parmName = string(parmStart, (int) (parser.fChar - parmStart));
                        parser.skipWhiteSpace();
                        do {
                            size_t nextComma = parmName.find(',');
                            string piece;
                            if (string::npos == nextComma) {
                                piece = parmName;
                                parmName = "";
                            } else {
                                piece = parmName.substr(0, nextComma);
                                parmName = parmName.substr(nextComma + 1);
                            }
                            if (sawParam) {
                                if (multiline) {
                                    this->lf(1);
                                }
                                this->writeEndTag();
                            } else {
                                if (sawComment) {
                                    this->nl();
                                }
                                this->lf(2);
                            }
                            foundParams.emplace_back(piece);
                            this->writeTag("Param", piece);
                            this->writeSpace(2);
                            this->writeBlock(parser.fEnd - parser.fChar, parser.fChar);
                            this->lf(1);
                            sawParam = true;
                            sawComment = false;
                        } while (parmName.length());
                        parser.skipTo(parser.fEnd);
                    } else if (parser.startsWith("return ") || parser.startsWith("returns ")) {
                        parser.skipWord("return");
                        if ('s' == parser.peek()) {
                            parser.next();
                        }
                        if (sawParam) {
                            if (multiline) {
                                this->lf(1);
                            }
                            this->writeEndTag();
                        }
                        this->checkForMissingParams(methodParams, foundParams);
                        sawParam = false;
                        sawComment = false;
                        multiline = false;
                        this->lf(2);
                        this->writeTag("Return");
                        this->writeSpace(2);
                        this->writeBlock(parser.fEnd - parser.fChar, parser.fChar);
                        this->lf(1);
                        sawReturn = true;
                        parser.skipTo(parser.fEnd);
                    } else {
                        this->reportError("unexpected doxygen directive");
                    }
                } while (!parser.eof());
            } else 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->lfAlways(sawComment || sawParam || sawReturn ? 1 : 2);
                    if (sawParam || sawReturn) {
                        this->indentToColumn(8);
                    }
                    this->writeBlock(length, start);
                    this->writeSpace();
                    sawComment = true;
                    if (sawParam || sawReturn) {
                        multiline = true;
                    }
                }
            }
        }
    }
    if (sawParam || sawReturn) {
        if (multiline) {
            this->lf(1);
        }
        this->writeEndTag();
    }
    if (!sawReturn) {
        if (!sawParam) {
            if (sawComment) {
                this->nl();
            }
            this->lf(2);
        }
        this->checkForMissingParams(methodParams, foundParams);
    }
    if (methodHasReturn != sawReturn) {
        if (!methodHasReturn) {
            this->reportError("unexpected doxygen return");
        } else {
            if (sawComment) {
                this->nl();
            }
            this->lf(2);
            this->writeIncompleteTag("Return");
        }
    }
}

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) {
    this->writeTag("Enum", name);
    this->lf(2);
    this->writeTag("Code");
    this->lfAlways(1);
    this->indentToColumn(4);
    this->writeString("enum");
    this->writeSpace();
    if ("_anonymous" != token.fName.substr(0, 10)) {
        this->writeString(token.fName);
        this->writeSpace();
    }
    this->writeString("{");
    this->lfAlways(1);
    for (auto& child : token.fChildren) {
        this->indentToColumn(8);
        this->writeString(child->fName);
        if (child->length()) {
            this->writeSpace();
            this->writeBlock(child->length(), child->fContentStart);
        }
        if (',' != fLastChar) {
            this->writeString(",");
        }
        this->lfAlways(1);
    }
    this->indentToColumn(4);
    this->writeString("};");
    this->lf(1);
    this->writeString("##");
    this->lf(2);
    this->dumpComment(token);
    for (auto& child : token.fChildren) {
        // TODO: get comments before or after const values
        this->writeTag("Const");
        this->writeSpace();
        this->writeString(child->fName);
        TextParser val(child);
        if (!val.eof()) {
            if ('=' == val.fStart[0] || ',' == val.fStart[0]) {
                val.next();
                val.skipSpace();
                const char* valEnd = val.anyOf(",\n");
                if (!valEnd) {
                    valEnd = val.fEnd;
                }
                this->writeSpace();
                this->writeBlock(valEnd - val.fStart, val.fStart);
            } else {
                this->writeSpace();
                this->writeDefinition(*child);
            }
        }
        this->lf(1);
        for (auto comment : child->fChildren) {
            if (MarkType::kComment == comment->fMarkType) {
                TextParser parser(comment);
                parser.skipExact("*");
                parser.skipExact("*");
                while (!parser.eof() && parser.skipWhiteSpace()) {
                    parser.skipExact("*");
                    parser.skipWhiteSpace();
                    const char* start = parser.fChar;
                    parser.skipToEndBracket('\n');
                    this->lf(1);
                    this->writeBlock(parser.fChar - start, start);
                }
            }
        }
        this->writeEndTag();
    }
    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);
    this->writeTag("Subtopic", "Overview");
    this->writeTag("Populate");
    this->writeEndTag();
    this->lf(2);
    if (!fIDefineMap.empty()) {
        this->writeTag("Subtopic", "Define");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (!fIFunctionMap.empty()) {
        this->writeTag("Subtopic", "Function");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (!fIEnumMap.empty()) {
        this->writeTag("Subtopic", "Enum");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (!fITemplateMap.empty()) {
        this->writeTag("Subtopic", "Template");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (!fITypedefMap.empty()) {
        this->writeTag("Subtopic", "Typedef");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (!fIUnionMap.empty()) {
        this->writeTag("Subtopic", "Union");
        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) {
        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:
                this->dumpMethod(*def, globalsName);
                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
    SkDebugf("wrote %s\n", fileName.c_str());
    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);
}

void IncludeParser::dumpMethod(const Definition& token, string className) {
    this->writeTag("Method");
    this->writeSpace();

    string name = string(token.fStart ? token.fStart : token.fContentStart,
            token.length());
    if (this->isOperator(token)) {
        string spaceConst(" const");
        size_t constPos = name.rfind(spaceConst);
        if (name.length() - spaceConst.length() == constPos) {
            name = name.substr(0, constPos) + "_const";
        }
    }
    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);
}

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);
    }
    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);
    bool hasClass = false;
    bool hasConst = !fIEnumMap.empty();
    bool hasConstructor = false;
    bool hasMember = false;
    bool hasOperator = false;
    bool hasStruct = false;
    for (const auto& oneClass : fIClassMap) {
        if (skClassName + "::" != oneClass.first.substr(0, skClassName.length() + 2)) {
            continue;
        }
        hasClass = true;
        break;
    }
    for (const auto& oneStruct : fIStructMap) {
        if (skClassName + "::" != oneStruct.first.substr(0, skClassName.length() + 2)) {
            continue;
        }
        hasStruct = true;
        break;
    }
    for (const auto& token : classMap.fTokens) {
        if (Definition::Type::kMark != token.fType || MarkType::kMethod != token.fMarkType) {
            continue;
        }
        if (this->isInternalName(token)) {
            continue;
        }
        if (token.fUndocumented) {
            continue;
        }
        if (this->isConstructor(token, skClassName)) {
            hasConstructor = true;
            continue;
        }
        if (this->isOperator(token)) {
            hasOperator = true;
            continue;
        }
        if (this->isClone(token)) {
            continue;
        }
        hasMember = true;
    }
    this->writeTag("Subtopic", "Overview");
    this->writeTag("Populate");
    this->writeEndTag();
    this->lf(2);

    if (hasClass) {
        this->writeTag("Subtopic", "Class");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (hasConst) {
        this->writeTag("Subtopic", "Constant");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (hasConstructor) {
        this->writeTag("Subtopic", "Constructor");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (hasOperator) {
        this->writeTag("Subtopic", "Operator");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (hasMember) {
        this->writeTag("Subtopic", "Member_Function");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    if (hasStruct) {
        this->writeTag("Subtopic", "Struct");
        this->writeTag("Populate");
        this->writeEndTag();
        this->lf(2);
    }
    for (auto& oneEnum : fIEnumMap) {
        this->writeBlockSeparator();
        this->dumpEnum(*oneEnum.second, oneEnum.first);
        this->lf(2);
        this->writeTag("Example");
        this->lfcr();
        this->writeString("// incomplete");
        this->writeEndTag();
        this->lf(2);
        this->writeTag("SeeAlso", "incomplete");
        this->lf(2);
        this->writeEndTag("Enum", oneEnum.first);
        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;
    MarkType markType = MarkType::kNone;
    if ("Constant" == inContents) {
        mapPtr = &fIConstMap;
        markType = MarkType::kConst;
    } 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, markType);
    }
    return result;
}

bool IncludeParser::findCommentAfter(const Definition& includeDef, Definition* 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) {
    // 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;
    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
    SkASSERT(string::npos != methodName.find('('));
    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) {
            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;
    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 = { "experimental",  "deprecated", "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)
                && ("deprecated" != match || "" == parser.anyWord(butNot, 2))) {
            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);
            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;
        // 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;
        memberStart->fUndocumented = undocumented;
        markupMember->fUndocumented = undocumented;
        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;
    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;
    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;
    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;
    markupChild->fTerminator = markupChild->fContentEnd;
    IClassDefinition& classDef = fIClassMap[markupDef->fName];
    classDef.fTypedefs[nameStr] = markupChild;
    child->fName = markupDef->fName + "::" + nameStr;
    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;
                    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);
                            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 = SkOSPath::Join(docs, baseName.c_str());
    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;
}
