/*
 * 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 "bookmaker.h"
#include "SkOSFile.h"
#include "SkOSPath.h"

const char IncludeParser::gAttrDeprecated[] = "SK_ATTR_DEPRECATED";
const size_t IncludeParser::kAttrDeprecatedLen = sizeof(gAttrDeprecated) - 1;

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         },
    { "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 && 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;
        }
    }
}

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;
            this->addDefinition(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;
}

#include <sstream>
#include <iostream>

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;
        }
        RootDefinition* root = &finder->second;
        root->clearVisited();
    }
    for (auto& classMapper : fIClassMap) {
        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);
                }
            }
        }
        auto& classMap = classMapper.second;
        auto& tokens = classMap.fTokens;
        for (const auto& token : tokens) {
            if (token.fPrivate) {
                continue;
            }
            string fullName = classMapper.first + "::" + token.fName;
            const Definition* def = root->find(fullName, RootDefinition::AllowParens::kYes);
            switch (token.fMarkType) {
                case MarkType::kMethod: {
                    if (this->isInternalName(token)) {
                        continue;
                    }
                    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 (gAttrDeprecated == token.fName) {
                            fAttrDeprecated = &token;
                            break;
                        }
                        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 (!root->fDeprecated) {
                            SkDebugf("method missing from bmh: %s\n", fullName.c_str());
                            fFailed = true;
                        }
                        break;
                    }
                    if (def->crossCheck2(token)) {
                        def->fVisited = true;
                        if (token.fDeprecated && !def->fDeprecated) {
                            fFailed = !def->reportError<bool>("expect bmh to be marked deprecated");
                        }
                    } 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 anonName = className + "::" + string(lastUnderscore,
                                    wordEnd - lastUnderscore) + 's';
                            def = root->find(anonName, RootDefinition::AllowParens::kYes);
                        }
                        if (!def) {
                            if (!root->fDeprecated) {
                                SkDebugf("enum missing from bmh: %s\n", fullName.c_str());
                                fFailed = true;
                            }
                            break;
                        }
                    }
                    def->fVisited = true;
                    for (auto& child : def->fChildren) {
                        if (MarkType::kCode == child->fMarkType) {
                            def = child;
                            break;
                        }
                    }
                    if (MarkType::kCode != def->fMarkType) {
                        if (!root->fDeprecated) {
                            SkDebugf("enum code missing from bmh: %s\n", fullName.c_str());
                            fFailed = true;
                        }
                        break;
                    }
                    if (def->crossCheck(token)) {
                        def->fVisited = true;
                    } else {
                        SkDebugf("enum differs from bmh: %s\n", def->fName.c_str());
                        fFailed = true;
                    }
                    for (auto& child : token.fChildren) {
                        string constName = MarkType::kEnumClass == token.fMarkType ?
                                fullName : className;
                        constName += "::" + child->fName;
                        def = root->find(constName, RootDefinition::AllowParens::kYes);
                        if (!def) {
                            string innerName = classMapper.first + "::" + child->fName;
                            def = root->find(innerName, RootDefinition::AllowParens::kYes);
                        }
                        if (!def) {
                            if (string::npos == child->fName.find("Legacy_")) {
                                if (!root->fDeprecated) {
                                    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 if (!root->fDeprecated) {
                        SkDebugf("member missing from bmh: %s\n", fullName.c_str());
                        fFailed = true;
                    }
                    break;
                case MarkType::kTypedef:
                    if (def) {
                        def->fVisited = true;
                    } else if (!root->fDeprecated) {
                        SkDebugf("typedef missing from bmh: %s\n", fullName.c_str());
                        fFailed = true;
                    }
                    break;
                case MarkType::kConst:
                    if (def) {
                        def->fVisited = true;
                    } else if (!root->fDeprecated) {
                        SkDebugf("const missing from bmh: %s\n", fullName.c_str());
                        fFailed = true;
                    }
                    break;
                default:
                    SkASSERT(0);  // unhandled
                    break;
            }
        }
    }
    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;
    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) {
    //     start here;
        // 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 (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);
}

bool IncludeParser::findComments(const Definition& includeDef, Definition* markupDef) {
    // add comment preceding class, if any
    const 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)) {
            return false;
        }
        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::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;
}

// 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 (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::parseComment(string filename, const char* start, const char* end,
        int lineCount, Definition* markupDef) {
    TextParser parser(filename, start, end, lineCount);
    // parse doxygen if present
    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;
}

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;
        }
        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;
    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;
        }
        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;
    }
    classDef.fDefines[nameStr] = markupChild;
    return true;
}

bool IncludeParser::parseEnum(Definition* child, Definition* markupDef) {
	TextParser parser(child);
	parser.skipToEndBracket('{');
	if (parser.eof()) {
		return true;	// if enum is a forward declaration, do nothing
	}
	parser.next();
	string nameStr;
    if (child->fTokens.size() > 0) {
        auto token = child->fTokens.begin();
        if (Definition::Type::kKeyWord == token->fType && KeyWord::kClass == token->fKeyWord) {
            token = token->fTokens.begin();
        }
        if (Definition::Type::kWord == token->fType) {
            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;
        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;
    TextParser enumName(child);
    enumName.skipExact("enum ");
    enumName.skipWhiteSpace();
    if (enumName.skipExact("class ")) {
        enumName.skipWhiteSpace();
        markupChild->fMarkType = MarkType::kEnumClass;
    }
    const char* nameStart = enumName.fChar;
    enumName.skipToSpace();
    if (markupDef) {
        markupChild->fName = markupDef->fName + "::" +
                string(nameStart, (size_t) (enumName.fChar - nameStart));
    }
    if (!this->findComments(*child, markupChild)) {
        return false;
    }
    const char* dataEnd;
    do {
        parser.skipWhiteSpace();
        if ('}' == parser.peek()) {
            break;
        }
        Definition* comment = nullptr;
        // note that comment, if any, can be before or after (on the same line, though) as member
        if ('#' == parser.peek()) {
            // fixme: handle preprecessor, but just skip it for now
            parser.skipToLineStart();
        }
        while (parser.startsWith("/*") || parser.startsWith("//")) {
            parser.next();
            const char* start = parser.fChar;
            const char* end;
            if ('*' == parser.peek()) {
                end = parser.strnstr("*/", parser.fEnd);
                parser.fChar = end;
                parser.next();
                parser.next();
            } else {
                end = parser.trimmedLineEnd();
                parser.skipToLineStart();
            }
            markupChild->fTokens.emplace_back(MarkType::kComment, start, end, parser.fLineCount,
                    markupChild, '\0');
            comment = &markupChild->fTokens.back();
            comment->fTerminator = end;
            if (!this->parseComment(parser.fFileName, start, end, parser.fLineCount, comment)) {
                return false;
            }
            parser.skipWhiteSpace();
        }
        parser.skipWhiteSpace();
        const char* memberStart = parser.fChar;
        if ('}' == memberStart[0]) {
            break;
        }
        // if there's comment on same the line as member def, output first as if it was before

        parser.skipToNonName();
        string memberName(memberStart, parser.fChar);
        if (parser.eof() || !parser.skipWhiteSpace()) {
            return parser.reportError<bool>("enum member must end with comma 1");
        }
        const char* dataStart = parser.fChar;
        if ('=' == parser.peek()) {
            parser.skipToEndBracket(',');
        }
        if (!parser.eof() && '#' == parser.peek()) {
            // fixme: handle preprecessor, but just skip it for now
            continue;
        }
        if (parser.eof() || ',' != parser.peek()) {
            return parser.reportError<bool>("enum member must end with comma 2");
        }
        dataEnd = parser.fChar;
        const char* start = parser.anyOf("/\n");
        SkASSERT(start);
        parser.skipTo(start);
        if ('/' == parser.next()) {
            char slashStar = parser.next();
            if ('/' == slashStar || '*' == slashStar) {
                TextParserSave save(&parser);
                char doxCheck = parser.next();
                if ((slashStar != doxCheck && '!' != doxCheck) || '<' != parser.next()) {
                    save.restore();
                }
            }
            parser.skipWhiteSpace();
            const char* commentStart = parser.fChar;
            if ('/' == slashStar) {
                parser.skipToEndBracket('\n');
            } else {
                parser.skipToEndBracket("*/");
            }
            SkASSERT(!parser.eof());
            const char* commentEnd = parser.fChar;
            markupChild->fTokens.emplace_back(MarkType::kComment, commentStart, commentEnd,
                    parser.fLineCount, markupChild, '\0');
            comment = &markupChild->fTokens.back();
            comment->fTerminator = commentEnd;
        }
        markupChild->fTokens.emplace_back(MarkType::kMember, dataStart, dataEnd, parser.fLineCount,
                markupChild, '\0');
        Definition* member = &markupChild->fTokens.back();
        member->fName = memberName;
        if (comment) {
            member->fChildren.push_back(comment);
            comment->fPrivate = true;
        }
        markupChild->fChildren.push_back(member);
    } while (true);
    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);
        markupChild->fName = uniqueName;
        classDef.fEnums[uniqueName] = markupChild;
    }
    return true;
}

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;
    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("::");
    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;
        while (testIter != child->fParent->fTokens.end()) {
            testIter = std::next(testIter);
            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 (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;
        }
        fIFunctionMap[globalUniqueName] = globalMarkupChild;
        return true;
    }
    markupDef->fTokens.emplace_back(MarkType::kMethod, start, end, tokenIter->fLineCount,
            markupDef, '\0');
    Definition* markupChild = &markupDef->fTokens.back();
    // TODO: I wonder if there is a way to prevent looking up by operator[] (creating empty) ?
    {
        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;
        }
        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;
                default:
                    return child->reportError<bool>("unhandled keyword");
            }
            break;
        case Definition::Type::kBracket:
            switch (child->fBracket) {
                case Bracket::kParen:
                    if (fLastObject) {
                        TextParser checkDeprecated(child->fFileName, fLastObject->fTerminator + 1,
                                child->fStart, fLastObject->fLineCount);
                        if (!checkDeprecated.eof()) {
                            checkDeprecated.skipWhiteSpace();
                            if (checkDeprecated.startsWith(gAttrDeprecated)) {
                                fAttrDeprecated = child;
                                break;
                            }
                        }
                    }
                    {
                        auto tokenIter = child->fParent->fTokens.begin();
                        std::advance(tokenIter, child->fParentIndex);
                        tokenIter = std::prev(tokenIter);
                        TextParser previousToken(&*tokenIter);
                        if (previousToken.startsWith(gAttrDeprecated)) {
                            fAttrDeprecated = &*tokenIter;
                            break;
                        }
                        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");
                    }
                    if (fAttrDeprecated) {
                        Definition* lastMethod = &markupDef->fTokens.back();
                        lastMethod->fDeprecated = true;
                        fAttrDeprecated = nullptr;
                    }
                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:
                        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;
        }
        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;
    return true;
}

bool IncludeParser::parseUnion() {

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

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