/*
 * 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 <chrono>
#include <ctime>

#include "bmhParser.h"
#include "includeWriter.h"

bool IncludeWriter::checkChildCommentLength(const Definition* parent, MarkType childType) const {
    bool oneMember = false;
    for (auto& item : parent->fChildren) {
        if (childType != item->fMarkType) {
            continue;
        }
        oneMember = true;
        int lineLen = 0;
        for (auto& itemChild : item->fChildren) {
            if (MarkType::kLine == itemChild->fMarkType) {
                lineLen = itemChild->length();
                break;
            }
        }
        if (!lineLen) {
            item->reportError<void>("missing #Line");
        }
        if (fEnumItemCommentTab + lineLen >= 100) {
// if too long, remove spaces until it fits, or wrap
//            item->reportError<void>("#Line comment too long");
        }
    }
    return oneMember;
}

void IncludeWriter::checkEnumLengths(const Definition& child, string enumName, ItemLength* length) const {
    const Definition* enumItem = this->matchMemberName(enumName, child);
    if (std::any_of(enumItem->fChildren.begin(), enumItem->fChildren.end(),
            [](Definition* child){return MarkType::kNoJustify == child->fMarkType;})) {
        return;
    }
    string comment = this->enumMemberComment(enumItem, child);
    int lineLimit = 100 - fIndent - 7; // 7: , space //!< space
    if (length->fCurValue) {
        lineLimit -= 3; // space = space
    }
    if (length->fCurName + length->fCurValue + (int) comment.length() < lineLimit) {
        length->fLongestName = SkTMax(length->fLongestName, length->fCurName);
        length->fLongestValue = SkTMax(length->fLongestValue, length->fCurValue);
    }
}

void IncludeWriter::constOut(const Definition* memberStart, const Definition* bmhConst) {
    const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
        memberStart->fContentStart;
    this->firstBlockTrim((int) (bodyEnd - fStart), fStart);  // may write nothing
    this->lf(2);
    this->indentDeferred(IndentKind::kConstOut);
    if (fStructEnded) {
        fIndent = fICSStack.size() * 4;
        fStructEnded = false;
    }
    // comment may be legitimately empty; typedef may not have separate comment (for now)
    fReturnOnWrite = true;
    bool commentHasLength = this->descriptionOut(bmhConst, SkipFirstLine::kYes, Phrase::kNo);
    fReturnOnWrite = false;
    if (commentHasLength) {
        this->writeCommentHeader();
        fIndent += 4;
        if (!this->descriptionOut(bmhConst, SkipFirstLine::kYes, Phrase::kNo)) {
            return memberStart->reportError<void>("expected description for const");
        }
        fIndent -= 4;
        this->writeCommentTrailer(OneLine::kNo);
    }
    this->setStart(memberStart->fContentStart, memberStart);
}

bool IncludeWriter::descriptionOut(const Definition* def, SkipFirstLine skipFirstLine,
            Phrase phrase) {
    bool wroteSomething = false;
    const char* commentStart = def->fContentStart;
    if (SkipFirstLine::kYes == skipFirstLine) {
        TextParser parser(def);
        SkAssertResult(parser.skipLine());
        commentStart = parser.fChar;
    }
    int commentLen = (int) (def->fContentEnd - commentStart);
    bool breakOut = false;
    SkDEBUGCODE(bool wroteCode = false);
    const Definition* lastDescription = def;
    for (auto prop : def->fChildren) {
        fLastDescription = lastDescription;
        lastDescription = prop;
        switch (prop->fMarkType) {
            case MarkType::kCode: {
                bool literal = false;
                bool literalOutdent = false;
                commentLen = (int) (prop->fStart - commentStart);
                if (commentLen > 0) {
                    SkASSERT(commentLen < 1000);
                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
                        if (fReturnOnWrite) {
                            return true;
                        }
                        this->lf(2);
                        wroteSomething = true;
                    }
                }
                size_t childSize = prop->fChildren.size();
                if (childSize) {
                    if (MarkType::kLiteral == prop->fChildren[0]->fMarkType) {
                        SkASSERT(1 == childSize || 2 == childSize);  // incomplete
                        SkASSERT(1 == childSize || MarkType::kOutdent == prop->fChildren[1]->fMarkType);
                        commentStart = prop->fChildren[childSize - 1]->fContentStart;
                        literal = true;
                        literalOutdent = 2 == childSize &&
                                MarkType::kOutdent == prop->fChildren[1]->fMarkType;
                    }
                }
                commentLen = (int) (prop->fContentEnd - commentStart);
                SkASSERT(commentLen > 0);
                if (literal) {
                    if (!fReturnOnWrite && !literalOutdent) {
                        fIndent += 4;
                    }
                    wroteSomething |= this->writeBlockIndent(commentLen, commentStart, false);
                    if (fReturnOnWrite) {
                        return true;
                    }
                    if (!fReturnOnWrite) {
                        this->lf(2);
                        if (!literalOutdent) {
                            fIndent -= 4;
                        }
                    }
                    SkDEBUGCODE(wroteCode = true);
                }
                commentStart = prop->fTerminator;
                } break;
            case MarkType::kBug: {
                if (fReturnOnWrite) {
                    return true;
                }
                string bugstr("(see skbug.com/" + string(prop->fContentStart,
                    prop->fContentEnd - prop->fContentStart) + ')');
                this->writeString(bugstr);
                this->lfcr();
                wroteSomething = true;
            }
            case MarkType::kFormula: {
                commentLen = prop->fStart - commentStart;
                if (commentLen > 0) {
                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
                        if (fReturnOnWrite) {
                            return true;
                        }
                        if (commentLen > 1 && '\n' == prop->fStart[-1]) {
                            this->lf(1);
                        } else {
                            this->writeSpace();
                        }
                        wroteSomething = true;
                    }
                }
                int saveIndent = fIndent;
                if (fIndent < fColumn + 1) {
                    fIndent = fColumn + 1;
                }
                wroteSomething |= this->writeBlockIndent(prop->length(), prop->fContentStart, true);
                fIndent = saveIndent;
                if (wroteSomething && fReturnOnWrite) {
                    return true;
                }
                commentStart = prop->fTerminator;
                commentLen = (int) (def->fContentEnd - commentStart);
                if (!fReturnOnWrite) {
                    if (commentLen > 1 && ' ' == commentStart[0] && !fLinefeeds) {
                        this->writeSpace();
                    }
                }
                } break;
            case MarkType::kDetails:
            case MarkType::kIn:
            case MarkType::kLine:
            case MarkType::kToDo:
                commentLen = (int) (prop->fStart - commentStart);
                if (commentLen > 0) {
                    SkASSERT(commentLen < 1000);
                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, Phrase::kNo)) {
                        if (fReturnOnWrite) {
                            return true;
                        }
                        this->lfcr();
                        wroteSomething = true;
                    }
                }
                commentStart = prop->fTerminator;
                commentLen = (int) (def->fContentEnd - commentStart);
                break;
            case MarkType::kList:
                commentLen = prop->fStart - commentStart;
                if (commentLen > 0) {
                    if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart,
                            Phrase::kNo)) {
                        if (fReturnOnWrite) {
                            return true;
                        }
                        this->lfcr();
                        wroteSomething = true;
                    }
                }
                for (auto row : prop->fChildren) {
                    SkASSERT(MarkType::kRow == row->fMarkType);
                    for (auto column : row->fChildren) {
                        SkASSERT(MarkType::kColumn == column->fMarkType);
                        if (fReturnOnWrite) {
                            return true;
                        }
                        this->writeString("-");
                        this->writeSpace();
                        wroteSomething |= this->descriptionOut(column, SkipFirstLine::kNo, Phrase::kNo);
                        this->lf(1);
                    }
                }
                commentStart = prop->fTerminator;
                commentLen = (int) (def->fContentEnd - commentStart);
                if ('\n' == commentStart[0] && '\n' == commentStart[1]) {
                    this->lf(2);
                }
                break;
            case MarkType::kPhraseRef: {
                commentLen = prop->fStart - commentStart;
                if (commentLen > 0) {
                    if (fReturnOnWrite) {
                        return true;
                    }
                    this->rewriteBlock(commentLen, commentStart, Phrase::kNo);
                    // ince we don't do line wrapping, always insert LF before phrase
                    this->lfcr();   // TODO: remove this once rewriteBlock rewraps paragraphs
                    wroteSomething = true;
                }
                auto iter = fBmhParser->fPhraseMap.find(prop->fName);
                if (fBmhParser->fPhraseMap.end() == iter) {
                    return this->reportError<bool>("missing phrase definition");
                }
                Definition* phraseDef = iter->second;
                // TODO: given TextParser(commentStart, prop->fStart + up to #) return if
                // it ends with two of more linefeeds, ignoring other whitespace
                Phrase defIsPhrase = '\n' == prop->fStart[0] && '\n' == prop->fStart[-1] ?
                        Phrase::kNo : Phrase::kYes;
                if (Phrase::kNo == defIsPhrase) {
                    this->lf(2);
                }
                const char* start = phraseDef->fContentStart;
                int length = phraseDef->length();
                auto propParams = prop->fChildren.begin();
                // can this share code or logic with mdout somehow?
                for (auto child : phraseDef->fChildren) {
                    if (MarkType::kPhraseParam == child->fMarkType) {
                        continue;
                    }
                    int localLength = child->fStart - start;
                    if (fReturnOnWrite) {
                        return true;
                    }
                    this->rewriteBlock(localLength, start, defIsPhrase);
                    start += localLength;
                    length -= localLength;
                    SkASSERT(propParams != prop->fChildren.end());
                    if (fColumn > 0) {
                        this->writeSpace();
                    }
                    this->writeString((*propParams)->fName);
                    localLength = child->fContentEnd - child->fStart;
                    start += localLength;
                    length -= localLength;
                    if (isspace(start[0])) {
                        this->writeSpace();
                    }
                    defIsPhrase = Phrase::kYes;
                    wroteSomething = true;
                }
                if (length > 0) {
                    if (fReturnOnWrite) {
                        return true;
                    }
                    this->rewriteBlock(length, start, defIsPhrase);
                }
                commentStart = prop->fContentStart;
                commentLen = (int) (def->fContentEnd - commentStart);
                if (!fReturnOnWrite) {
                    if ('\n' == commentStart[0] && '\n' == commentStart[1]) {
                        this->lf(2);
                    }
                }
                } break;
            default:
                commentLen = (int) (prop->fStart - commentStart);
                breakOut = true;
        }
        if (breakOut) {
            break;
        }
    }
    if (!breakOut) {
        commentLen = (int) (def->fContentEnd - commentStart);
    }
    SkASSERT(wroteCode || (commentLen > 0 && commentLen < 1500));
    if (commentLen > 0) {
        if (Wrote::kNone != this->rewriteBlock(commentLen, commentStart, phrase)) {
            if (fReturnOnWrite) {
                return true;
            }
            wroteSomething = true;
        }
    }
    SkASSERT(!fReturnOnWrite || !wroteSomething);
    return wroteSomething;
}

void IncludeWriter::enumHeaderOut(RootDefinition* root, const Definition& child) {
    const Definition* enumDef = nullptr;
    const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
            child.fContentStart;
    this->firstBlockTrim((int) (bodyEnd - fStart), fStart);  // may write nothing
    this->lf(2);
    this->indentDeferred(IndentKind::kEnumHeader);
    fDeferComment = nullptr;
    this->setStart(child.fContentStart, &child);
    const auto& nameDef = child.fTokens.front();
    string fullName;
    if (nullptr != nameDef.fContentEnd) {
        TextParser enumClassCheck(&nameDef);
        const char* start = enumClassCheck.fStart;
        size_t len = (size_t) (enumClassCheck.fEnd - start);
        bool enumClass = enumClassCheck.skipExact("class ");
        if (enumClass) {
            start = enumClassCheck.fChar;
            const char* end = enumClassCheck.anyOf(" \n;{");
            len = (size_t) (end - start);
        }
        string enumName(start, len);
        if (enumClass) {
            child.fChildren[0]->fName = enumName;
        }
        fullName = root->fName + "::" + enumName;
        enumDef = root->find(enumName, RootDefinition::AllowParens::kNo);
        if (!enumDef) {
            enumDef = root->find(fullName, RootDefinition::AllowParens::kNo);
        }
        if (!enumDef) {
            auto mapEntry = fBmhParser->fEnumMap.find(enumName);
            if (fBmhParser->fEnumMap.end() != mapEntry) {
                enumDef = &mapEntry->second;
            }
        }
        if (!enumDef && enumName == root->fName) {
            enumDef = root;
        }
        SkASSERT(enumDef);
        // child[0] should be #Code comment starts at child[0].fTerminator
            // though skip until #Code is found (in case there's a #ToDo, etc)
        // child[1] should be #Const comment ends at child[1].fStart
        // comment becomes enum header (if any)
    } else {
        string enumName(root->fName);
        enumName += "::_anonymous";
        if (fAnonymousEnumCount > 1) {
            enumName += '_' + to_string(fAnonymousEnumCount);
        }
        enumDef = root->find(enumName, RootDefinition::AllowParens::kNo);
        SkASSERT(enumDef);
        ++fAnonymousEnumCount;
    }
    Definition* codeBlock = nullptr;
    const char* commentStart = nullptr;
    bool firstCodeBlocks = true;
    bool wroteHeader = false;
    bool lastAnchor = false;
//    SkDEBUGCODE(bool foundConst = false);
    for (auto test : enumDef->fChildren) {
        if (MarkType::kCode == test->fMarkType && firstCodeBlocks) {
            codeBlock = test;
            commentStart = codeBlock->fTerminator;
            continue;
        } else if (codeBlock) {
            firstCodeBlocks = false;
        }
        if (!codeBlock) {
            continue;
        }
        const char* commentEnd = test->fStart;
        if (!wroteHeader &&
                !this->contentFree((int) (commentEnd - commentStart), commentStart)) {
            if (fIndentNext) {
                // FIXME: how can I tell where fIdentNext gets cleared?
                this->indentIn(IndentKind::kEnumChild);
            }
            this->writeCommentHeader();
            this->writeString("\\enum");
            if (fullName.length() > 0) {
                this->writeSpace();
                this->writeString(fullName.c_str());
            }
            this->indentIn(IndentKind::kEnumChild2);
            this->lfcr();
            wroteHeader = true;
        }
        if (lastAnchor) {
            if (commentEnd - commentStart > 1) {
                SkASSERT('\n' == commentStart[0]);
                if (' ' == commentStart[1]) {
                    this->writeSpace();
                }
            }
            lastAnchor = false;
        }
        this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
        if (MarkType::kAnchor == test->fMarkType || MarkType::kCode == test->fMarkType) {
            bool newLine = commentEnd - commentStart > 1 &&
                '\n' == commentEnd[-1] && '\n' == commentEnd[-2];
            commentStart = test->fContentStart;
            commentEnd = MarkType::kAnchor == test->fMarkType ? test->fChildren[0]->fStart :
                    test->fContentEnd;
            if (newLine) {
                this->lf(2);
            } else {
                this->writeSpace();
            }
            if (MarkType::kAnchor == test->fMarkType) {
                this->rewriteBlock((int) (commentEnd - commentStart), commentStart, Phrase::kNo);
            } else {
                this->writeBlock((int) (commentEnd - commentStart), commentStart);
                this->lf(2);
            }
            lastAnchor = true;   // this->writeSpace();
        }
        commentStart = test->fTerminator;
        if (MarkType::kConst == test->fMarkType) {
            SkASSERT(codeBlock);  // FIXME: check enum for correct order earlier
//            SkDEBUGCODE(foundConst = true);
            break;
        }
    }
 //   SkASSERT(codeBlock);
 //   SkASSERT(foundConst);
    if (wroteHeader) {
        this->indentOut();
        this->lfcr();
        this->writeCommentTrailer(OneLine::kNo);
    }
    Definition* braceHolder = child.fChildren[0];
    if (KeyWord::kClass == braceHolder->fKeyWord) {
        braceHolder = braceHolder->fChildren[0];
    }
    bodyEnd = braceHolder->fContentStart;
    SkASSERT('{' == bodyEnd[0]);
    ++bodyEnd;
    this->lfcr();
    this->writeBlock((int) (bodyEnd - fStart), fStart); // write include "enum Name {"
    this->indentIn(IndentKind::kEnumHeader2);
    this->singleLF();
    this->setStart(bodyEnd, braceHolder);
    fEnumDef = enumDef;
}

const Definition* IncludeWriter::enumMemberForComment(const Definition* currentEnumItem) const {
    for (auto constItem : currentEnumItem->fChildren) {
        if (MarkType::kLine == constItem->fMarkType) {
            return constItem;
        }
    }
    SkASSERT(0);
    return nullptr;
}

string IncludeWriter::enumMemberComment(const Definition* currentEnumItem,
        const Definition& child) const {
    // #Const should always be followed by #Line, so description follows that
    string shortComment;
    for (auto constItem : currentEnumItem->fChildren) {
        if (MarkType::kLine == constItem->fMarkType) {
            shortComment = string(constItem->fContentStart, constItem->length());
            break;
        }
    }
    if (!shortComment.length()) {
        currentEnumItem->reportError<void>("missing #Line or #Deprecated or #Experimental");
    }
    return shortComment;
}

IncludeWriter::ItemState IncludeWriter::enumMemberName(
        const Definition& child, const Definition* token, Item* item, LastItem* last,
        const Definition** currentEnumItem) {
    TextParser parser(fFileName, last->fStart, last->fEnd, fLineCount);
    parser.skipWhiteSpace();
    item->fName = string(parser.fChar, (int) (last->fEnd - parser.fChar));
    *currentEnumItem = this->matchMemberName(item->fName, child);
    if (token) {
        this->setStart(token->fContentEnd, token);
        TextParser enumLine(token->fFileName, last->fEnd, token->fContentStart, token->fLineCount);
        const char* end = enumLine.anyOf(",}=");
        SkASSERT(end);
        if ('=' == *end) {  // write enum value
            last->fEnd = token->fContentEnd;
            item->fValue = string(token->fContentStart, (int) (last->fEnd - token->fContentStart));
            return ItemState::kValue;
        }
    }
    return ItemState::kComment;
}

void IncludeWriter::enumMemberOut(const Definition* currentEnumItem, const Definition& child,
        const Item& item, Preprocessor& preprocessor) {
    SkASSERT(currentEnumItem);
    string shortComment = this->enumMemberComment(currentEnumItem, child);
    int enumItemValueTab =
            SkTMax((int) item.fName.length() + fIndent + 1, fEnumItemValueTab); // 1: ,
    int valueLength = item.fValue.length();
    int assignLength = valueLength ? valueLength + 3 : 0; // 3: space = space
    int enumItemCommentTab = SkTMax(enumItemValueTab + assignLength, fEnumItemCommentTab);
    int trimNeeded = enumItemCommentTab + shortComment.length() - (100 - (sizeof("//!< ") - 1));
    bool crAfterName = false;
    if (trimNeeded > 0) {
        if (item.fValue.length()) {
            int valueSpare = SkTMin(trimNeeded,                  // 3 below: space = space
                    (int) (enumItemCommentTab - enumItemValueTab - item.fValue.length() - 3));
            SkASSERT(valueSpare >= 0);
            trimNeeded -= valueSpare;
            enumItemCommentTab -= valueSpare;
        }
        if (trimNeeded > 0) {
            int nameSpare = SkTMin(trimNeeded, (int) (enumItemValueTab - item.fName.length()
                    - fIndent - 1));  // 1: ,
            SkASSERT(nameSpare >= 0);
            trimNeeded -= nameSpare;
            enumItemValueTab -= nameSpare;
            enumItemCommentTab -= nameSpare;
        }
        if (trimNeeded > 0) {
            crAfterName = true;
            if (!valueLength) {
                this->enumMemberForComment(currentEnumItem)->reportError<void>("comment too long");
            } else if (valueLength + fIndent + 8 + shortComment.length() > // 8: addtional indent
                    100 - (sizeof(", //!< ") - 1)) { // -1: zero-terminated string
                this->enumMemberForComment(currentEnumItem)->reportError<void>("comment 2 long");
            }                                    // 2: = space
            enumItemValueTab = fEnumItemValueTab +  2                 // 2: , space
                    - SkTMax(0, fEnumItemValueTab + 2 + valueLength +    2 - fEnumItemCommentTab);
            enumItemCommentTab = SkTMax(enumItemValueTab + valueLength + 2, fEnumItemCommentTab);
        }
    }
    this->lfcr();
    this->writeString(item.fName);
    int saveIndent = fIndent;
    if (item.fValue.length()) {
        if (!crAfterName) {
            this->indentToColumn(enumItemValueTab);
        } else {
            this->writeSpace();
        }
        this->writeString("=");
        if (crAfterName) {
            this->lfcr();
            fIndent = enumItemValueTab;
        } else {
            this->writeSpace();
        }
        this->writeString(item.fValue);
    }
    this->writeString(",");
    this->indentToColumn(enumItemCommentTab);
    this->writeString("//!<");
    this->writeSpace();
    this->rewriteBlock(shortComment.length(), shortComment.c_str(), Phrase::kYes);
    this->lfcr();
    fIndent = saveIndent;
    if (preprocessor.fStart) {
        SkASSERT(preprocessor.fEnd);
        int saveIndent = fIndent;
        fIndent = SkTMax(0, fIndent - 8);
        this->lf(2);
        this->writeBlock(
                (int) (preprocessor.fEnd - preprocessor.fStart), preprocessor.fStart);
        this->lfcr();
        fIndent = saveIndent;
        preprocessor.reset();
    }
}

// iterate through include tokens and find how much remains for 1 line comments
// put ones that fit on same line, ones that are too big wrap
void IncludeWriter::enumMembersOut(Definition& child) {
    ItemState state = ItemState::kNone;
    const Definition* currentEnumItem = nullptr;
    LastItem last = { nullptr, nullptr };
    auto brace = child.fChildren[0];
    if (KeyWord::kClass == brace->fKeyWord) {
        brace = brace->fChildren[0];
    }
    SkASSERT(Bracket::kBrace == brace->fBracket);
    vector<IterState> iterStack;
    iterStack.emplace_back(brace->fTokens.begin(), brace->fTokens.end());
    IterState* iterState = &iterStack[0];
    Preprocessor preprocessor;
    Item item;
    while (iterState->fDefIter != iterState->fDefEnd) {
        auto& token = *iterState->fDefIter++;
        if (this->enumPreprocessor(&token, MemberPass::kOut, iterStack, &iterState,
                &preprocessor)) {
            continue;
        }
        if (ItemState::kName == state) {
            state = this->enumMemberName(child, &token, &item, &last, &currentEnumItem);
        }
        if (ItemState::kValue == state) {
            TextParser valueEnd(token.fFileName, last.fEnd, token.fContentStart, token.fLineCount);
            const char* end = valueEnd.anyOf(",}");
            if (!end) {  // write expression continuation
                item.fValue += string(last.fEnd, (int) (token.fContentEnd - last.fEnd));
                continue;
            }
        }
        if (ItemState::kNone != state && currentEnumItem) {
            this->enumMemberOut(currentEnumItem, child, item, preprocessor);
            item.reset();
            this->setStartBack(token.fContentStart, &token);
            state = ItemState::kNone;
            last.fStart = nullptr;
        }
        SkASSERT(ItemState::kNone == state || !currentEnumItem);
        if (!last.fStart) {
            last.fStart = fStart;
        }
        last.fEnd = token.fContentEnd;
        state = ItemState::kName;
    }
    if (ItemState::kName == state) {
        state = this->enumMemberName(child, nullptr, &item, &last, &currentEnumItem);
    }
    if ((ItemState::kValue == state || ItemState::kComment == state) && currentEnumItem) {
        this->enumMemberOut(currentEnumItem, child, item, preprocessor);
    }
    this->indentOut();
}

bool IncludeWriter::enumPreprocessor(Definition* token, MemberPass pass,
        vector<IterState>& iterStack, IterState** iterState, Preprocessor* preprocessor) {
    if (token && Definition::Type::kBracket == token->fType) {
        if (Bracket::kSlashSlash == token->fBracket) {
            if (MemberPass::kOut == pass) {
                this->setStart(token->fContentEnd, token);
            }
            return true;  // ignore old inline comments
        }
        if (Bracket::kSlashStar == token->fBracket) {
            if (MemberPass::kOut == pass) {
                this->setStart(token->fContentEnd + 1, token);
            }
            return true;  // ignore old inline comments
        }
        if (Bracket::kPound == token->fBracket) {  // preprocessor wraps member
            preprocessor->fDefinition = token;
            preprocessor->fStart = token->fContentStart;
            if (KeyWord::kIf == token->fKeyWord || KeyWord::kIfdef == token->fKeyWord) {
                iterStack.emplace_back(token->fTokens.begin(), token->fTokens.end());
                *iterState = &iterStack.back();
                preprocessor->fWord = true;
            } else if (KeyWord::kEndif == token->fKeyWord || KeyWord::kElif == token->fKeyWord
                    || KeyWord::kElse == token->fKeyWord) {
                iterStack.pop_back();
                *iterState = &iterStack.back();
                preprocessor->fEnd = token->fContentEnd;
                if (KeyWord::kElif == token->fKeyWord) {
                    iterStack.emplace_back(token->fTokens.begin(), token->fTokens.end());
                    *iterState = &iterStack.back();
                    preprocessor->fWord = true;
                }
            } else {
                SkASSERT(0); // incomplete
            }
            return true;
        }
        if (preprocessor->fDefinition) {
            if (Bracket::kParen == token->fBracket) {
                preprocessor->fEnd = token->fContentEnd;
                SkASSERT(')' == *preprocessor->fEnd);
                ++preprocessor->fEnd;
                return true;
            }
            SkASSERT(0);  // incomplete
        }
        return true;
    }
    if (token && Definition::Type::kWord != token->fType) {
        SkASSERT(0); // incomplete
    }
    if (preprocessor->fWord) {
        preprocessor->fWord = false;
        preprocessor->fEnd = token->fContentEnd;
        return true;
    }
    return false;
}

void IncludeWriter::enumSizeItems(const Definition& child) {
    ItemState state = ItemState::kNone;
    ItemLength lengths = { 0, 0, 0, 0 };
    const char* lastEnd = nullptr;
    auto brace = child.fChildren[0];
    if (KeyWord::kClass == brace->fKeyWord) {
        brace = brace->fChildren[0];
    }
    SkASSERT(Bracket::kBrace == brace->fBracket);
    vector<IterState> iterStack;
    iterStack.emplace_back(brace->fTokens.begin(), brace->fTokens.end());
    IterState* iterState = &iterStack[0];
    Preprocessor preprocessor;
    string enumName;
    bool undocumented = false;
    while (iterState->fDefIter != iterState->fDefEnd) {
        auto& token = *iterState->fDefIter++;
        if (this->enumPreprocessor(&token, MemberPass::kCount, iterStack, &iterState,
                &preprocessor)) {
            continue;
        }
        if (ItemState::kName == state) {
            TextParser enumLine(token.fFileName, lastEnd, token.fContentStart, token.fLineCount);
            const char* end = enumLine.anyOf(",}=");
            SkASSERT(end);
            state = '=' == *end ? ItemState::kValue : ItemState::kComment;
            if (ItemState::kValue == state) {
                lastEnd = token.fContentEnd;
                lengths.fCurValue = (int) (lastEnd - token.fContentStart);
                continue;
            }
        }
        if (ItemState::kValue == state) {
            TextParser valueEnd(token.fFileName, lastEnd, token.fContentStart, token.fLineCount);
            const char* end = valueEnd.anyOf(",}");
            if (!end) {  // write expression continuation
                lengths.fCurValue += (int) (token.fContentEnd - lastEnd);
                continue;
            }
        }
        if (ItemState::kNone != state) {
            if (!undocumented) {
                this->checkEnumLengths(child, enumName, &lengths);
            }
            lengths.fCurValue = 0;
            state = ItemState::kNone;
        }
        SkASSERT(ItemState::kNone == state);
        lastEnd = token.fContentEnd;
        lengths.fCurName = (int) (lastEnd - token.fContentStart);
        enumName = string(token.fContentStart, lengths.fCurName);
        undocumented = token.fUndocumented;
        state = ItemState::kName;
    }
    if (ItemState::kNone != state && !undocumented) {
        this->checkEnumLengths(child, enumName, &lengths);
    }
    fEnumItemValueTab = lengths.fLongestName + fIndent + 1 /* 1: , */ ;
    if (lengths.fLongestValue) {
        lengths.fLongestValue += 3; // 3: space = space
    }
    fEnumItemCommentTab = fEnumItemValueTab + lengths.fLongestValue + 1 ; // 1: space before //!<
    // iterate through bmh children and see which comments fit on include lines
    if (!this->checkChildCommentLength(fEnumDef, MarkType::kConst)) {
        fEnumDef->reportError<void>("expected at least one #Const in #Enum");
    }
}

const Definition* IncludeWriter::matchMemberName(string matchName, const Definition& child) const {
    const Definition* parent = &child;
    if (KeyWord::kEnum == child.fKeyWord && child.fChildren.size() > 0
            && KeyWord::kClass == child.fChildren[0]->fKeyWord) {
        matchName = child.fChildren[0]->fName + "::" + matchName;
    }
    do {
        if (KeyWord::kStruct == parent->fKeyWord || KeyWord::kClass == parent->fKeyWord) {
            matchName = parent->fName + "::" + matchName;
        }
    } while ((parent = parent->fParent));
    const Definition* enumItem = nullptr;
    for (auto testItem : fEnumDef->fChildren) {
        if (MarkType::kConst != testItem->fMarkType) {
            continue;
        }
        if (matchName != testItem->fName) {
            continue;
        }
        enumItem = testItem;
        break;
    }
    return enumItem;    // returns nullptr if matchName is undocumented
}

// walk children and output complete method doxygen description
void IncludeWriter::methodOut(Definition* method, const Definition& child) {
    if (fPendingMethod) {
        this->indentOut();
        fPendingMethod = false;
    }
    fBmhMethod = method;
    fMethodDef = &child;
    fContinuation = nullptr;
    fDeferComment = nullptr;
    Definition* csParent = method->csParent();
    if (csParent && (0 == fIndent || fIndentNext)) {
        this->indentIn(IndentKind::kMethodOut);
        fIndentNext = false;
    }
    if (method->fChildren.end() != std::find_if(method->fChildren.begin(), method->fChildren.end(),
            [](const Definition* def) { return MarkType::kPopulate == def->fMarkType; } )) {
        std::list<Definition>::iterator iter;
        const Definition* childPtr = &child;
        SkDEBUGCODE(bool sawMethod = false);
        do {
            int commentIndex = childPtr->fParentIndex;
            iter = childPtr->fParent->fTokens.begin();
            std::advance(iter, commentIndex);
            SkDEBUGCODE(sawMethod |= MarkType::kMethod == iter->fMarkType);
            while (--commentIndex >= 0) {
                std::advance(iter, -1);
                if (Bracket::kSlashStar == iter->fBracket) {
                    SkASSERT(sawMethod);
                    break;
                }
                SkASSERT(!sawMethod);
                SkDEBUGCODE(sawMethod |= MarkType::kMethod == iter->fMarkType);
            }
            if (MarkType::kMethod != iter->fMarkType) {
                break;
            }
            childPtr = childPtr->fParent;
            SkDEBUGCODE(sawMethod = true);
        } while (true);
        SkASSERT(Bracket::kSlashSlash == iter->fBracket || Bracket::kSlashStar == iter->fBracket);
        this->lf(2);
        this->writeString("/");
        this->writeBlock(iter->length(), iter->fContentStart);
        this->lfcr();
    } else {
        this->writeCommentHeader();
        fIndent += 4;
        this->descriptionOut(method, SkipFirstLine::kNo, Phrase::kNo);
        // compute indention column
        size_t column = 0;
        bool hasParmReturn = false;
        for (auto methodPart : method->fChildren) {
            if (MarkType::kParam == methodPart->fMarkType) {
                column = SkTMax(column, methodPart->fName.length());
                hasParmReturn = true;
            } else if (MarkType::kReturn == methodPart->fMarkType) {
                hasParmReturn = true;
            }
        }
        if (hasParmReturn) {
            this->lf(2);
            column += fIndent + sizeof("@return ");
            int saveIndent = fIndent;
            for (auto methodPart : method->fChildren) {
                if (MarkType::kParam == methodPart->fMarkType) {
                    this->writeString("@param");
                    this->writeSpace();
                    this->writeString(methodPart->fName.c_str());
                } else if (MarkType::kReturn == methodPart->fMarkType) {
                    this->writeString("@return");
                } else {
                    continue;
                }
                this->indentToColumn(column);
                fIndent = column;
                this->descriptionOut(methodPart, SkipFirstLine::kNo, Phrase::kYes);
                fIndent = saveIndent;
                this->lfcr();
            }
        } else {
            this->lfcr();
        }
        fIndent -= 4;
        this->lfcr();
        this->writeCommentTrailer(OneLine::kNo);
    }
    fBmhMethod = nullptr;
    fMethodDef = nullptr;
    fEnumDef = nullptr;
    fWroteMethod = true;
}

void IncludeWriter::structOut(const Definition* root, const Definition& child,
        const char* commentStart, const char* commentEnd) {
    this->writeCommentHeader();
    this->writeString("\\");
    SkASSERT(MarkType::kClass == child.fMarkType || MarkType::kStruct == child.fMarkType);
    this->writeString(MarkType::kClass == child.fMarkType ? "class" : "struct");
    this->writeSpace();
    this->writeString(child.fName.c_str());
    fIndent += 4;
    this->lfcr();
    this->rewriteBlock((int)(commentEnd - commentStart), commentStart, Phrase::kNo);
    fIndent -= 4;
    this->lfcr();
    this->writeCommentTrailer(OneLine::kNo);
}

bool IncludeWriter::findEnumSubtopic(string undername, const Definition** rootDefPtr) const {
    const Definition* subtopic = fEnumDef->fParent;
    string subcheck = subtopic->fFiddle + '_' + undername;
    auto iter = fBmhParser->fTopicMap.find(subcheck);
    if (iter == fBmhParser->fTopicMap.end()) {
        return false;
    }
    *rootDefPtr = iter->second;
    return true;
}

Definition* IncludeWriter::findMemberCommentBlock(const vector<Definition*>& bmhChildren,
        string name) const {
    for (auto memberDef : bmhChildren) {
        if (MarkType::kMember != memberDef->fMarkType) {
            continue;
        }
        string match = memberDef->fName;
        // if match.endsWith(name) ...
        if (match.length() >= name.length() &&
                0 == match.compare(match.length() - name.length(), name.length(), name)) {
            return memberDef;
        }
    }
    for (auto memberDef : bmhChildren) {
        if (MarkType::kSubtopic != memberDef->fMarkType && MarkType::kTopic != memberDef->fMarkType) {
            continue;
        }
        Definition* result = this->findMemberCommentBlock(memberDef->fChildren, name);
        if (result) {
            return result;
        }
    }
    return nullptr;
}

Definition* IncludeWriter::findMethod(string name, RootDefinition* root) const {
    if (root) {
        return root->find(name, RootDefinition::AllowParens::kNo);
    }
    auto methodIter = fBmhParser->fMethodMap.find(name);
    if (fBmhParser->fMethodMap.end() == methodIter) {
        return nullptr;
    }
    return &methodIter->second;
}


void IncludeWriter::firstBlock(int size, const char* data) {
     SkAssertResult(this->firstBlockTrim(size, data));
}

bool IncludeWriter::firstBlockTrim(int size, const char* data) {
    bool result = this->writeBlockTrim(size, data);
    if (fFirstWrite) {
        auto fileInfo = std::find_if(fRootTopic->fChildren.begin(), fRootTopic->fChildren.end(),
                [](const Definition* def){ return MarkType::kFile == def->fMarkType; } );
        if (fRootTopic->fChildren.end() != fileInfo) {
            this->writeCommentHeader();
            this->writeString("\\file");
            this->writeSpace();
            size_t lastSlash = fFileName.rfind('/');
            if (string::npos == lastSlash) {
                lastSlash = fFileName.rfind('\\');
            }
            string fileName = fFileName.substr(lastSlash + 1);
            this->writeString(fileName);
            this->lf(2);
            fIndent += 4;
            this->descriptionOut(*fileInfo, SkipFirstLine::kNo, Phrase::kNo);
            fIndent -= 4;
            this->writeCommentTrailer(OneLine::kNo);
        }
        fFirstWrite = false;
    }
    return result;
}

void IncludeWriter::setStart(const char* start, const Definition* def) {
    SkASSERT(start >= fStart);
    this->setStartBack(start, def);
}

void IncludeWriter::setStartBack(const char* start, const Definition* def) {
    fStartSetter = def;
    fStart = start;
}

Definition* IncludeWriter::structMemberOut(const Definition* memberStart, const Definition& child) {
    const char* blockStart = !fWroteMethod && fDeferComment ? fDeferComment->fContentEnd : fStart;
    const char* blockEnd = fWroteMethod && fDeferComment ? fDeferComment->fStart - 1 :
            memberStart->fStart;
    this->firstBlockTrim((int) (blockEnd - blockStart), blockStart);
    this->indentDeferred(IndentKind::kStructMember);
    fWroteMethod = false;
    string name(child.fContentStart, (int) (child.fContentEnd - child.fContentStart));
    Definition* commentBlock = this->findMemberCommentBlock(fBmhStructDef->fChildren, name);
    if (!commentBlock) {
        return memberStart->reportError<Definition*>("member missing comment block 2");
    }
    auto lineIter = std::find_if(commentBlock->fChildren.begin(), commentBlock->fChildren.end(),
        [](const Definition* def){ return MarkType::kLine == def->fMarkType; } );
    SkASSERT(commentBlock->fChildren.end() != lineIter);
    const Definition* lineDef = *lineIter;
    if (fStructMemberLength > 100) {
        this->writeCommentHeader();
        this->writeSpace();
        this->rewriteBlock(lineDef->length(), lineDef->fContentStart, Phrase::kYes);
        this->writeCommentTrailer(OneLine::kYes);
    }
    this->lfcr();
    this->writeBlock((int) (child.fStart - memberStart->fContentStart),
            memberStart->fContentStart);
    this->indentToColumn(fStructMemberTab);
    this->writeString(name.c_str());
    auto tokenIter = child.fParent->fTokens.begin();
    std::advance(tokenIter, child.fParentIndex + 1);
    Definition* valueStart = &*tokenIter;
    while (Definition::Type::kPunctuation != tokenIter->fType) {
        std::advance(tokenIter, 1);
        SkASSERT(child.fParent->fTokens.end() != tokenIter);
    }
    Definition* valueEnd = &*tokenIter;
    if (valueStart != valueEnd) {
        this->indentToColumn(fStructValueTab);
        this->writeString("=");
        this->writeSpace();
        this->writeBlock((int) (valueEnd->fStart - valueStart->fContentStart),
                valueStart->fContentStart);
    }
    this->writeString(";");
    if (fStructMemberLength <= 100) {
        this->indentToColumn(fStructCommentTab);
        this->writeString("//!<");
        this->writeSpace();
        this->rewriteBlock(lineDef->length(), lineDef->fContentStart, Phrase::kYes);
    }
    this->lf(1);
    return valueEnd;
}

// const and constexpr and #define aren't contained in a braces like struct and enum.
// use a bmh subtopic to group like ones together, then measure them in the include as if
// they were formally linked together
void IncludeWriter::constSizeMembers(const RootDefinition* root) {
    // fBmhConst->fParent is subtopic containing all grouped const expressions
    // fConstDef is token of const include name, hopefully on same line as const start
    string rootPrefix = root ? root->fName + "::" : "";
    const Definition* test = fConstDef;
    int tokenIndex = test->fParentIndex;
    int longestName = 0;
    int longestValue = 0;
    int longestComment = 0;
    const Definition* subtopic = fBmhConst->fParent;
    SkASSERT(subtopic);
    SkASSERT(MarkType::kSubtopic == subtopic->fMarkType);
    // back up to first token on line
    size_t lineCount = test->fLineCount;
    const Definition* last;
    auto tokenIter = test->fParent->fTokens.begin();
    std::advance(tokenIter, tokenIndex);
    do {
        last = test;
        std::advance(tokenIter, -1);
        test = &*tokenIter;
        SkASSERT(test->fParentIndex == --tokenIndex);
    } while (lineCount == test->fLineCount);
    test = last;
    for (auto child : subtopic->fChildren) {
        if (MarkType::kConst != child->fMarkType) {
            continue;
        }
        // expect found name to be on the left of assign
        // expect assign
        // expect semicolon
        // no parens, no braces
        while (rootPrefix + test->fName != child->fName) {
            std::advance(tokenIter, 1);
            test = &*tokenIter;
            SkASSERT(lineCount >= test->fLineCount);
        }
        ++lineCount;
        TextParser constText(test);
        const char* nameEnd = constText.trimmedBracketEnd('=');
        SkAssertResult(constText.skipToEndBracket('='));
        const char* valueEnd = constText.trimmedBracketEnd(';');
        auto lineIter = std::find_if(child->fChildren.begin(), child->fChildren.end(),
                [](const Definition* def){ return MarkType::kLine == def->fMarkType; });
        SkASSERT(child->fChildren.end() != lineIter);
        longestName = SkTMax(longestName, (int) (nameEnd - constText.fStart));
        longestValue = SkTMax(longestValue, (int) (valueEnd - constText.fChar));
        longestComment = SkTMax(longestComment, (*lineIter)->length());
    }
    // write fStructValueTab, fStructCommentTab
    fConstValueTab = longestName + fIndent + 1;
    fConstCommentTab = fConstValueTab + longestValue + 2;
    fConstLength = fConstCommentTab + longestComment + (int) sizeof("//!<");
}

bool IncludeWriter::defineOut(const Definition& def) {
    if (def.fTokens.size() < 1) {
        return false;
    }
    auto& child = def.fTokens.front();
    string name(child.fContentStart, child.length());
    auto defIter = fBmhParser->fDefineMap.find(name);
    if (fBmhParser->fDefineMap.end() == defIter) {
        return false;
    }
    const Definition& bmhDef = defIter->second;
    this->constOut(&def, &bmhDef);
    return true;
}

void IncludeWriter::structSizeMembers(const Definition& child) {
    int longestType = 0;
    Definition* typeStart = nullptr;
    int longestName = 0;
    int longestValue = 0;
    int longestComment = 0;
    SkASSERT(child.fChildren.size() == 1 || child.fChildren.size() == 2);
    bool inEnum = false;
    bool inMethod = false;
    bool inMember = false;
    auto brace = child.fChildren[0];
    SkASSERT(Bracket::kBrace == brace->fBracket);
    for (auto& token : brace->fTokens) {
        if (Definition::Type::kBracket == token.fType) {
            if (Bracket::kSlashSlash == token.fBracket) {
                continue;  // ignore old inline comments
            }
            if (Bracket::kSlashStar == token.fBracket) {
                continue;  // ignore old inline comments
            }
            if (Bracket::kParen == token.fBracket) {
                if (inMethod) {
                    continue;
                }
                break;
            }
            if (Bracket::kAngle == token.fBracket) {
                // in template param
                continue;
            }
            SkASSERT(0); // incomplete
        }
        if (Definition::Type::kKeyWord == token.fType) {
            switch (token.fKeyWord) {
                case KeyWord::kEnum:
                    inEnum = true;
                    break;
                case KeyWord::kConst:
                case KeyWord::kConstExpr:
                case KeyWord::kStatic:
                case KeyWord::kInt:
                case KeyWord::kUint8_t:
                case KeyWord::kUint16_t:
                case KeyWord::kUint32_t:
                case KeyWord::kUint64_t:
                case KeyWord::kUintPtr_t:
                case KeyWord::kUnsigned:
                case KeyWord::kSize_t:
                case KeyWord::kFloat:
                case KeyWord::kBool:
                case KeyWord::kChar:
                case KeyWord::kVoid:
                    if (!typeStart) {
                        typeStart = &token;
                    }
                    break;
                default:
                    break;
            }
            continue;
        }
        if (Definition::Type::kPunctuation == token.fType) {
            if (inEnum) {
                SkASSERT(Punctuation::kSemicolon == token.fPunctuation);
                inEnum = false;
            }
            if (inMethod) {
                if (Punctuation::kColon == token.fPunctuation) {
                    inMethod = false;
                } else if (Punctuation::kLeftBrace == token.fPunctuation) {
                    inMethod = false;
                } else if (Punctuation::kSemicolon == token.fPunctuation) {
                    inMethod = false;
                } else {
                    SkASSERT(0);  // incomplete
                }
            }
            if (inMember) {
                SkASSERT(Punctuation::kSemicolon == token.fPunctuation);
                typeStart = nullptr;
                inMember = false;
            }
            continue;
        }
        if (Definition::Type::kWord != token.fType) {
            SkASSERT(0); // incomplete
        }
        if (MarkType::kMember == token.fMarkType) {
            TextParser typeStr(token.fFileName, typeStart->fContentStart, token.fContentStart,
                    token.fLineCount);
            typeStr.trimEnd();
            longestType = SkTMax(longestType, (int) (typeStr.fEnd - typeStr.fStart));
            longestName = SkTMax(longestName, (int) (token.fContentEnd - token.fContentStart));
            typeStart->fMemberStart = true;
            inMember = true;
            string tokenName(token.fContentStart, (int) (token.fContentEnd - token.fContentStart));
            Definition* commentBlock = this->findMemberCommentBlock(fBmhStructDef->fChildren,
                    tokenName);
            if (!commentBlock) {
                return token.reportError<void>("member missing comment block 1");
            }
            auto lineIter = std::find_if(commentBlock->fChildren.begin(),
                    commentBlock->fChildren.end(),
                    [](const Definition* def){ return MarkType::kLine == def->fMarkType; } );
            SkASSERT(commentBlock->fChildren.end() != lineIter);
            const Definition* lineDef = *lineIter;
            longestComment = SkTMax(longestComment, lineDef->length());
            continue;
        }
        if (MarkType::kMethod == token.fMarkType) {
            inMethod = true;
            continue;
        }
        SkASSERT(MarkType::kNone == token.fMarkType);
        if (typeStart) {
            if (inMember) {
                longestValue =
                        SkTMax(longestValue, (int) (token.fContentEnd - token.fContentStart));
            }
        } else {
            typeStart = &token;
        }
    }
    fStructMemberTab = longestType + fIndent + 1 /* space before name */ ;
    fStructValueTab = fStructMemberTab + longestName + 2 /* space ; */ ;
    fStructCommentTab = fStructValueTab;
    if (longestValue) {
        fStructCommentTab += longestValue + 3 /* space = space */ ;
        fStructValueTab -= 1 /* ; */ ;
    }
    fStructMemberLength = fStructCommentTab + longestComment;
    // iterate through struct to ensure that members' comments fit on line
    // struct or class may not have any members
    (void) this->checkChildCommentLength(fBmhStructDef, MarkType::kMember);
}

static bool find_start(const Definition* startDef, const char* start) {
    for (const auto& child : startDef->fTokens) {
        if (child.fContentStart == start) {
            return MarkType::kMethod == child.fMarkType;
        }
        if (child.fContentStart >= start) {
            break;
        }
        if (find_start(&child, start)) {
            return true;
        }
    }
    return false;
}

bool IncludeWriter::populate(Definition* def, ParentPair* prevPair, RootDefinition* root) {
    if (!def->fTokens.size()) {
        return true;
    }
    ParentPair pair = { def, prevPair };
    // write bulk of original include up to class, method, enum, etc., excepting preceding comment
    // find associated bmh object
    // write any associated comments in Doxygen form
    // skip include comment
    // if there is a series of same named methods, write one set of comments, then write all methods
    string methodName;
    Definition* method = nullptr;
    Definition* clonedMethod = nullptr;
    const Definition* memberStart = nullptr;
    const Definition* memberEnd = nullptr;
    fContinuation = nullptr;
    bool inStruct = false;
    bool inConstructor = false;
    bool inInline = false;
    bool eatOperator = false;
    bool sawConst = false;
    bool staticOnly = false;
    bool sawTypedef = false;
    Definition* deferredTypedefComment = nullptr;
    const Definition* requireDense = nullptr;
    const Definition* startDef = nullptr;
    for (auto& child : def->fTokens) {
        if (KeyWord::kInline == child.fKeyWord) {
            continue;
        }
        if (KeyWord::kOperator == child.fKeyWord && method &&
                Definition::MethodType::kOperator == method->fMethodType) {
            eatOperator = true;
            continue;
        }
        if (eatOperator) {
            if (Bracket::kSquare == child.fBracket || Bracket::kParen == child.fBracket) {
                continue;
            }
            eatOperator = false;
            fContinuation = nullptr;
            if (KeyWord::kConst == child.fKeyWord) {
                continue;
            }
        }
        if (memberEnd) {
            if (memberEnd != &child) {
                continue;
            }
            startDef = &child;
            this->setStart(child.fContentStart + 1, &child);
            memberEnd = nullptr;
        }
        if (child.fPrivate) {
            if (MarkType::kMethod == child.fMarkType) {
                inInline = true;
            }
            continue;
        }
        if (inInline) {
            if (Definition::Type::kKeyWord == child.fType) {
                SkASSERT(MarkType::kMethod != child.fMarkType);
                continue;
            }
            if (Definition::Type::kPunctuation == child.fType) {
                if (Punctuation::kLeftBrace == child.fPunctuation) {
                    inInline = false;
                } else {
                    SkASSERT(Punctuation::kAsterisk == child.fPunctuation);
                }
                continue;
            }
            if (Definition::Type::kWord == child.fType) {
                string name(child.fContentStart, child.fContentEnd - child.fContentStart);
                SkASSERT(string::npos != name.find("::"));
                continue;
            }
            if (Definition::Type::kBracket == child.fType) {
                SkASSERT(Bracket::kParen == child.fBracket);
                continue;
            }
        }
        if (fContinuation) {
            if (Definition::Type::kKeyWord == child.fType) {
                if (KeyWord::kFriend == child.fKeyWord ||
                        KeyWord::kSK_API == child.fKeyWord) {
                    continue;
                }
                const IncludeKey& includeKey = kKeyWords[(int) child.fKeyWord];
                if (KeyProperty::kNumber == includeKey.fProperty) {
                    continue;
                }
            }
            if (Definition::Type::kBracket == child.fType) {
                if (Bracket::kAngle == child.fBracket) {
                    continue;
                }
                if (Bracket::kParen == child.fBracket) {
                    if (!clonedMethod) {
                        if (inConstructor) {
                            fContinuation = child.fContentStart;
                        }
                        continue;
                    }
                    int alternate = 1;
                    ptrdiff_t childLen = child.fContentEnd - child.fContentStart;
                    SkASSERT(')' == child.fContentStart[childLen]);
                    ++childLen;
                    do {
                        TextParser params(clonedMethod->fFileName, clonedMethod->fStart,
                            clonedMethod->fContentStart, clonedMethod->fLineCount);
                        params.skipToEndBracket('(');
                        if (params.startsWith(child.fContentStart, childLen)) {
                            this->methodOut(clonedMethod, child);
                            sawConst = false;
                            break;
                        }
                        ++alternate;
                        string alternateMethod = methodName + '_' + to_string(alternate);
                       clonedMethod = this->findMethod(alternateMethod, root);
                    } while (clonedMethod);
                    if (!clonedMethod) {
                        return child.reportError<bool>("cloned method not found");
                    }
                    clonedMethod = nullptr;
                    continue;
                }
            }
            if (Definition::Type::kWord == child.fType) {
                if (clonedMethod) {
                    continue;
                }
                size_t len = (size_t) (child.fContentEnd - child.fContentStart);
                const char operatorStr[] = "operator";
                size_t operatorLen = sizeof(operatorStr) - 1;
                if (len >= operatorLen && !strncmp(child.fContentStart, operatorStr, operatorLen)) {
                    fContinuation = child.fContentEnd;
                    continue;
                }
            }
            if (Definition::Type::kPunctuation == child.fType &&
                    (Punctuation::kSemicolon == child.fPunctuation ||
                    Punctuation::kLeftBrace == child.fPunctuation ||
                    (Punctuation::kColon == child.fPunctuation && inConstructor))) {
                SkASSERT(fContinuation[0] == '(');
                const char* continueEnd = child.fContentStart;
                while (continueEnd > fContinuation && isspace(continueEnd[-1])) {
                    --continueEnd;
                }
                const char defaultTag[] = " = default";
                size_t tagSize = sizeof(defaultTag) - 1;
                const char* tokenEnd = continueEnd - tagSize;
                if (tokenEnd <= fContinuation || strncmp(tokenEnd, defaultTag, tagSize)) {
                    tokenEnd = continueEnd;
                }
                methodName += string(fContinuation, tokenEnd - fContinuation);
                if (string::npos != methodName.find('\n')) {
                    methodName.erase(std::remove(methodName.begin(), methodName.end(), '\n'),
                                    methodName.end());
                }
                method = this->findMethod(methodName, root);
                if (!method) {
                    return child.reportError<bool>("method not found");
                }
                this->methodOut(method, child);
                sawConst = false;
                continue;
            }
            if (Definition::Type::kPunctuation == child.fType &&
                    Punctuation::kAsterisk == child.fPunctuation &&
                    clonedMethod) {
                continue;
            }
            if (inConstructor) {
                continue;
            }
            method = this->findMethod(methodName + "()", root);
            if (method) {
                if (method->fCloned) {
                    clonedMethod = method;
                    continue;
                }
                this->methodOut(method, child);
                sawConst = false;
                continue;
            }
            if (KeyWord::kTemplate == child.fParent->fKeyWord) {
                // incomplete; no support to template specialization in public includes
                fContinuation = nullptr;
                continue;
            }
            return child.reportError<bool>("method not found");
        }
        if (Bracket::kSlashSlash == child.fBracket || Bracket::kSlashStar == child.fBracket) {
            if (!fDeferComment) {
                fDeferComment = &child;
            }
            continue;
        }
        if (MarkType::kMethod == child.fMarkType) {
            if (this->isInternalName(child)) {
                continue;
            }
            if (child.fUndocumented) {
                continue;
            }
            if (KeyWord::kTemplate == child.fParent->fKeyWord) {
                // todo: support template specializations
                continue;
            }
            const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
                    child.fContentStart;
            if (Definition::Type::kBracket == def->fType && Bracket::kDebugCode == def->fBracket) {
                auto tokenIter = def->fParent->fTokens.begin();
                std::advance(tokenIter, def->fParentIndex - 1);
                Definition* prior = &*tokenIter;
                if (Definition::Type::kBracket == def->fType &&
                        Bracket::kSlashStar == prior->fBracket) {
                    bodyEnd = prior->fContentStart - 1;
                }
            }
            // FIXME: roll end-trimming into writeBlockTrim call
            while (fStart < bodyEnd && ' ' >= bodyEnd[-1]) {
                --bodyEnd;
            }
            int blockSize = (int) (bodyEnd - fStart);
            SkASSERT(blockSize >= 0);
            if (blockSize) {
                string debugstr(fStart, blockSize);
                this->writeBlock(blockSize, fStart);
            }
            startDef = &child;
            this->setStart(child.fContentStart, &child);
            auto mapFind = fBmhParser->fMethodMap.find(child.fName);
            if (fBmhParser->fMethodMap.end() != mapFind) {
                inConstructor = false;
                method = &mapFind->second;
                methodName = child.fName;
            } else if (root) {
                methodName = root->fName + "::" + child.fName;
                size_t lastName = root->fName.rfind(':');
                lastName = string::npos == lastName ? 0 : lastName + 1;
                inConstructor = root->fName.substr(lastName) == child.fName;
                method = root->find(methodName, RootDefinition::AllowParens::kNo);
            }
            fContinuation = child.fContentEnd;
            if (!method) {
                continue;
            }
            if (method->fCloned) {
                clonedMethod = method;
                continue;
            }
            this->methodOut(method, child);
            sawConst = false;
            continue;
        }
        if (Definition::Type::kKeyWord == child.fType) {
            if (child.fUndocumented) {
                continue;
            }
            switch (child.fKeyWord) {
                case KeyWord::kStruct:
                case KeyWord::kClass:
                    fICSStack.push_back(&child);
                    fStructEnded = false;
                    fStructMemberTab = 0;
                    // if struct contains members, compute their name and comment tabs
                    if (child.fChildren.size() > 0) {
                        const ParentPair* testPair = &pair;
                        while ((testPair = testPair->fPrev)) {
                            if (KeyWord::kClass == testPair->fParent->fKeyWord) {
                                inStruct = fInStruct = true;
                                break;
                            }
                        }
                    }
                    if (fInStruct) {
                        // try child; root+child; root->parent+child; etc.
                        int trial = 0;
                        RootDefinition* search = root;
                        Definition* parent = search->fParent;
                        do {
                            string name;
                            if (0 == trial) {
                                name = child.fName;
                            } else if (1 == trial) {
                                name = root->fName + "::" + child.fName;
                            } else if (2 == trial) {
                                name = root->fName;
                            } else {
                                SkASSERT(parent);
                                name = parent->fName + "::" + child.fName;
                                search = parent->asRoot();
                                parent = search->fParent;
                            }
                            fBmhStructDef = search->find(name, RootDefinition::AllowParens::kNo);
                        } while (!fBmhStructDef && ++trial);
                        root = fBmhStructDef->asRoot();
                        SkASSERT(root);
                        fIndent += 4;
                        this->structSizeMembers(child);
                        fIndent -= 4;
                        SkASSERT(!fIndentNext);
                        fIndentNext = true;
                    }
                    if (child.fChildren.size() > 0) {
                        const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
                                child.fContentStart;
                        this->writeBlockTrim((int) (bodyEnd - fStart), fStart);
                        if (fPendingMethod) {
                            if (fIndent >= 4) {
                                this->indentOut();
                            }
                            fPendingMethod = false;
                        }
                        startDef = requireDense ? requireDense : &child;
                        if (requireDense) {
                            startDef = requireDense;
                            this->setStart(requireDense->fContentStart, requireDense);
                        } else {
                            startDef = &child;
                            this->setStart(child.fContentStart, &child);
                        }
                        requireDense = nullptr;
                        if (!fInStruct && (!root || child.fName != root->fName)) {
                            root = &fBmhParser->fClassMap[child.fName];
                            fRootTopic = root->fParent;
                            SkASSERT(!root->fVisited);
                            root->clearVisited();
#if 0
    // this seems better balanced; but real problem is probably fInStruct
                            if (fIndentStack.size() > 0) {
                                this->indentOut();
                            }
                            SkASSERT(!fIndent);
#else
                            fIndent = 0;
#endif
                            fBmhStructDef = root;
                        }
                        if (child.fName == root->fName) {
                            if (Definition* parent = root->fParent) {
                                if (MarkType::kTopic == parent->fMarkType ||
                                        MarkType::kSubtopic == parent->fMarkType) {
                                    const char* commentStart = root->fContentStart;
                                    unsigned index = 0;
                                    const char* commentEnd = root->fChildren[0]->fStart;
                                    int line = 1;
                                    do {
                                        TextParser parser(root->fFileName, commentStart, commentEnd, line);
                                        if (!parser.eof()) {
                                            parser.skipWhiteSpace();
                                        }
                                        if (!parser.eof()) {
                                            break;
                                        }
                                        commentStart = root->fChildren[index]->fTerminator;
                                        ++index;
                                        SkASSERT(index < root->fChildren.size());
                                        commentEnd = root->fChildren[index]->fStart;
                                    } while (true);
                                    this->structOut(root, *root, commentStart, commentEnd);
                                } else {
                                    SkASSERT(0); // incomplete
                                }
                            } else {
                                SkASSERT(0); // incomplete
                            }
                        } else {
                            SkASSERT(fInStruct);
                            Definition* priorBlock = fBmhStructDef;
                            Definition* codeBlock = nullptr;
                            Definition* nextBlock = nullptr;
                            for (auto test : fBmhStructDef->fChildren) {
                                if (MarkType::kCode == test->fMarkType) {
                                    SkASSERT(!codeBlock);  // FIXME: check enum earlier
                                    codeBlock = test;
                                    continue;
                                }
                                if (codeBlock) {
                                    nextBlock = test;
                                    break;
                                }
                                priorBlock = test;
                            }
                      // FIXME: trigger error earlier if inner #Struct or #Class is missing #Code
                            SkASSERT(codeBlock);
                            SkASSERT(nextBlock);  // FIXME: check enum for correct order earlier
                            const char* commentStart = codeBlock->fTerminator;
                            const char* commentEnd = nextBlock->fStart;
                    // FIXME: trigger error if #Code is present but comment is before it earlier
                            SkASSERT(priorBlock); // code always preceded by #Line (I think)
                            TextParser priorComment(priorBlock->fFileName,
                                    priorBlock->fTerminator, codeBlock->fStart,
                                    priorBlock->fLineCount);
                            priorComment.trimEnd();
                            if (!priorComment.eof()) {
                                return priorBlock->reportError<bool>(
                                        "expect no comment before #Code");
                            }
                            TextParser nextComment(codeBlock->fFileName, commentStart,
                                    commentEnd, codeBlock->fLineCount);
                            nextComment.trimEnd();
                            if (!priorComment.eof()) {
                                return priorBlock->reportError<bool>(
                                        "expect comment after #Code");
                            }
                            if (!nextComment.eof()) {

                            }
                            fIndentNext = true;
                            this->structOut(root, *fBmhStructDef, commentStart, commentEnd);
                        }
                        fDeferComment = nullptr;
                    } else {
                       // empty forward reference
                        bool writeTwo = '\n' == child.fContentStart[-1]
                                && '\n' == child.fContentStart[-2];
                        if (writeTwo) {
                            const char* bodyEnd = fDeferComment ? fDeferComment->fContentStart - 1 :
                                    child.fContentStart;
                            this->writeBlockTrim((int) (bodyEnd - fStart), fStart);
                            this->lf(writeTwo ? 2 : 1);
                            fIndent = 0;
                            this->writeBlockTrim(child.length() + 1, child.fContentStart);
                            writeTwo = '\n' == child.fContentEnd[1]
                                    && '\n' == child.fContentStart[2];
                            this->lf(writeTwo ? 2 : 1);
                            fStart = child.fContentEnd + 1;
                            fDeferComment = nullptr;
                        }
                    }
                    break;
                case KeyWord::kEnum: {
                    fInEnum = true;
                    this->enumHeaderOut(root, child);
                    this->enumSizeItems(child);
                } break;
                case KeyWord::kConst:
                case KeyWord::kConstExpr:
                    sawConst = !memberStart || staticOnly;
                    if (!memberStart) {
                        memberStart = &child;
                        staticOnly = true;
                    }
                    if (MarkType::kConst == child.fMarkType) {
                        auto constIter = fBmhParser->fConstMap.find(child.fName);
                        if (fBmhParser->fConstMap.end() != constIter) {
                            const RootDefinition& bmhConst = constIter->second;
                            this->constOut(&child, &bmhConst);
                            fDeferComment = nullptr;
                        }
                    }
                    break;
                case KeyWord::kStatic:
                    if (!memberStart) {
                        memberStart = &child;
                        staticOnly = true;
                    }
                    break;
                case KeyWord::kInt:
                case KeyWord::kUint8_t:
                case KeyWord::kUint16_t:
                case KeyWord::kUint32_t:
                case KeyWord::kUint64_t:
                case KeyWord::kUintPtr_t:
                case KeyWord::kUnsigned:
                case KeyWord::kSize_t:
                case KeyWord::kFloat:
                case KeyWord::kBool:
                case KeyWord::kChar:
                case KeyWord::kVoid:
                    staticOnly = false;
                    if (!memberStart) {
                        memberStart = &child;
                    }
                    break;
                case KeyWord::kAlignAs:
                case KeyWord::kPublic:
                case KeyWord::kPrivate:
                case KeyWord::kProtected:
                case KeyWord::kFriend:
                case KeyWord::kInline:
                case KeyWord::kSK_API:
                case KeyWord::kTemplate:
                case KeyWord::kUsing:
                    break;
                case KeyWord::kTypedef:
                    SkASSERT(!memberStart);
                    memberStart = &child;
                    deferredTypedefComment = fDeferComment;
                    sawTypedef = true;
                    break;
                case KeyWord::kSK_BEGIN_REQUIRE_DENSE:
                    requireDense = &child;
                    break;
                default:
                    SkASSERT(0);
            }
            if (KeyWord::kUint8_t == child.fKeyWord || KeyWord::kUint32_t == child.fKeyWord) {
                continue;
            } else {
                if (fInEnum && child.fChildren.size() > 0
                        && KeyWord::kClass == child.fChildren[0]->fKeyWord) {
                    if (!this->populate(child.fChildren[0], &pair, root)) {
                        return false;
                    }
                } else {
                    if (!this->populate(&child, &pair, root)) {
                        return false;
                    }
                    if (KeyWord::kClass == child.fKeyWord || KeyWord::kStruct == child.fKeyWord) {
                        fICSStack.pop_back();
                        fStructEnded = true;
                        if (fInStruct) {
                            fInStruct = false;
                            do {
                                SkASSERT(root);
                                root = const_cast<RootDefinition*>(root->fParent->asRoot());
                            } while (MarkType::kTopic == root->fMarkType ||
                                    MarkType::kSubtopic == root->fMarkType);
#if 0
                        }
                        if (MarkType::kStruct == root->fMarkType ||
                                MarkType::kClass == root->fMarkType) {
#else
                            SkASSERT(MarkType::kStruct == root->fMarkType ||
                                    MarkType::kClass == root->fMarkType);
#endif
                            fPendingMethod = false;
                            if (startDef) {
                                fPendingMethod = find_start(startDef, fStart);
                            }
                            fOutdentNext = !fPendingMethod;
                        }
                    }
                }
            }
            continue;
        }
        if (Definition::Type::kBracket == child.fType) {
            if (KeyWord::kEnum == child.fParent->fKeyWord ||
                    (KeyWord::kClass == child.fParent->fKeyWord && child.fParent->fParent &&
                    KeyWord::kEnum == child.fParent->fParent->fKeyWord)) {
                SkASSERT(Bracket::kBrace == child.fBracket);
                this->enumMembersOut(*child.fParent);
                this->writeString("};");
                this->lf(2);
                startDef = child.fParent;
                this->setStart(child.fParent->fContentEnd, child.fParent);
                SkASSERT(';' == fStart[0]);
                ++fStart;
                fDeferComment = nullptr;
                fInEnum = false;
                if (fIndentNext) {
//                    fIndent -= 4;
                    fIndentNext = false;
                }
                continue;
            }
            if (KeyWord::kDefine == child.fKeyWord && this->defineOut(child)) {
                fDeferComment = nullptr;
                continue;
            }
            fDeferComment = nullptr;
            if (KeyWord::kClass == def->fKeyWord || KeyWord::kStruct == def->fKeyWord) {
                fIndentNext = true;
            }
            if (!this->populate(&child, &pair, root)) {
                return false;
            }
            if (KeyWord::kClass == def->fKeyWord || KeyWord::kStruct == def->fKeyWord) {
                if (def->iRootParent() && (!fStartSetter
                        || MarkType::kMethod != fStartSetter->fMarkType)) {
                    this->setStart(child.fContentEnd, &child);
                    fDeferComment = nullptr;
                }
            }
            continue;
        }
        if (Definition::Type::kWord == child.fType) {
            if (MarkType::kMember == child.fMarkType) {
                if (!memberStart) {
                    auto iter = def->fTokens.begin();
                    std::advance(iter, child.fParentIndex - 1);
                    memberStart = &*iter;
                    staticOnly = false;
                }
                if (!fStructMemberTab) {
                    SkASSERT(KeyWord::kStruct == def->fParent->fKeyWord);
                    fIndent += 4;
                    this->structSizeMembers(*def->fParent);
                    fIndent -= 4;
                    fIndentNext = true;
                }
                SkASSERT(fBmhStructDef);
                memberEnd = this->structMemberOut(memberStart, child);
                startDef = &child;
                this->setStart(child.fContentEnd + 1, &child);
                fDeferComment = nullptr;
            } else if (MarkType::kNone == child.fMarkType && sawConst && fEnumDef) {
                const Definition* bmhConst = nullptr;
                string match;
                if (root) {
                    match = root->fName + "::";
                }
                match += string(child.fContentStart, child.fContentEnd - child.fContentStart);
                for (auto enumChild : fEnumDef->fChildren) {
                    if (MarkType::kConst == enumChild->fMarkType && enumChild->fName == match) {
                        bmhConst = enumChild;
                        break;
                    }
                }
                if (bmhConst) {
                    this->constOut(memberStart, bmhConst);
                    fDeferComment = nullptr;
                    sawConst = false;
                }
            } else if (MarkType::kNone == child.fMarkType && sawConst && !fEnumDef) {
                string match;
                if (root) {
                    match = root->fName + "::";
                    match += string(child.fContentStart, child.fContentEnd - child.fContentStart);
                    auto bmhClassIter = fBmhParser->fClassMap.find(root->fName);
                    if (fBmhParser->fClassMap.end() != bmhClassIter) {
                        RootDefinition& bmhClass = bmhClassIter->second;
                        auto constIter = std::find_if(bmhClass.fLeaves.begin(), bmhClass.fLeaves.end(),
                                [match](std::pair<const string, Definition>& leaf){ return match == leaf.second.fName; } );
                        if (bmhClass.fLeaves.end() != constIter) {
                            const Definition& bmhConst = constIter->second;
                            if (MarkType::kConst == bmhConst.fMarkType
                                    && MarkType::kSubtopic == bmhConst.fParent->fMarkType) {
                                fBmhConst = &bmhConst;
                                fConstDef = &child;
                            }
                        }
                    }
                }
            }
            if (child.fMemberStart) {
                memberStart = &child;
                staticOnly = false;
            }
            continue;
        }
        if (Definition::Type::kPunctuation == child.fType) {
            if (Punctuation::kSemicolon == child.fPunctuation) {
                if (sawConst && fBmhConst) {  // find bmh documentation. Parent must be subtopic.
                    const Definition* subtopic = fBmhConst->fParent;
                    SkASSERT(subtopic);
                    SkASSERT(MarkType::kSubtopic == subtopic->fMarkType);
                    auto firstConst = std::find_if(subtopic->fChildren.begin(),
                            subtopic->fChildren.end(),
                            [](const Definition* def){ return MarkType::kConst == def->fMarkType;});
                    SkASSERT(firstConst != subtopic->fChildren.end());
                    bool constIsFirst = *firstConst == fBmhConst;
                    if (constIsFirst) {  // If first #Const child, output subtopic description.
                        this->constOut(memberStart, subtopic);
                        // find member / value / comment tabs
                        // look for a one-to-one correspondence between bmh and include
                        this->constSizeMembers(root);
                        fDeferComment = nullptr;
                    }
                    // after const code, output #Line description as short comment
                    auto lineIter = std::find_if(fBmhConst->fChildren.begin(),
                            fBmhConst->fChildren.end(),
                            [](const Definition* def){ return MarkType::kLine == def->fMarkType; });
                    SkASSERT(fBmhConst->fChildren.end() != lineIter);
                    const Definition* lineDef = *lineIter;
                    if (fConstLength > 100) {
                        this->writeCommentHeader();
                        this->writeSpace();
                        this->rewriteBlock(lineDef->length(), lineDef->fContentStart, Phrase::kYes);
                        this->writeCommentTrailer(OneLine::kYes);
                    }
                    this->lfcr();
                    TextParser constText(memberStart);
                    const char* nameEnd = constText.trimmedBracketEnd('=');
                    SkAssertResult(constText.skipToEndBracket('='));
                    const char* valueEnd = constText.trimmedBracketEnd(';');
                    this->writeBlock((int) (nameEnd - memberStart->fContentStart),
                            memberStart->fContentStart);
                    this->indentToColumn(fConstValueTab);
                    this->writeBlock((int) (valueEnd - constText.fChar), constText.fChar);
                    this->writeString(";");
                    if (fConstLength <= 100) {
                        this->indentToColumn(fConstCommentTab);
                        this->writeString("//!<");
                        this->writeSpace();
                        this->rewriteBlock(lineDef->length(), lineDef->fContentStart, Phrase::kYes);
                    }
                    this->setStart(child.fContentStart + 1, &child);
                    fDeferComment = nullptr;
                    fBmhConst = nullptr;
                    sawConst = false;
                } else if (sawTypedef) {
                    const Definition* bmhTypedef = nullptr;
                    if (root) {
                        SkDEBUGCODE(auto classIter = fBmhParser->fClassMap.find(root->fName));
                        SkASSERT(fBmhParser->fClassMap.end() != classIter);
                        RootDefinition& classDef = fBmhParser->fClassMap[root->fName];
                        auto leafIter = classDef.fLeaves.find(memberStart->fName);
                        if (classDef.fLeaves.end() != leafIter) {
                            bmhTypedef = &leafIter->second;
                        }
                    }
                    if (!bmhTypedef) {
                        auto typedefIter = fBmhParser->fTypedefMap.find(memberStart->fName);
                        SkASSERT(fBmhParser->fTypedefMap.end() != typedefIter);
                        bmhTypedef = &typedefIter->second;
                    }
                    fDeferComment = deferredTypedefComment;
                    this->constOut(memberStart, bmhTypedef);
                    fDeferComment = nullptr;
                    sawTypedef = false;
                }
                memberStart = nullptr;
                staticOnly = false;
                if (inStruct) {
                    fInStruct = false;
                }
                continue;
            }
            if (Punctuation::kLeftBrace == child.fPunctuation ||
                    Punctuation::kColon == child.fPunctuation ||
                    Punctuation::kAsterisk == child.fPunctuation
                ) {
                continue;
            }
        }
    }
    return true;
}

bool IncludeWriter::populate(BmhParser& bmhParser) {
    bool allPassed = true;
    for (auto& includeMapper : fIncludeMap) {
        size_t lastSlash = includeMapper.first.rfind('/');
        if (string::npos == lastSlash) {
            lastSlash = includeMapper.first.rfind('\\');
        }
        if (string::npos == lastSlash || lastSlash >= includeMapper.first.length() - 1) {
            return this->reportError<bool>("malformed include name");
        }
        string fileName = includeMapper.first.substr(lastSlash + 1);
        if (".h" != fileName.substr(fileName.length() - 2)) {
            return this->reportError<bool>("expected fileName.h");
        }
        string skClassName = fileName.substr(0, fileName.length() - 2);
        this->reset();
        fOut = fopen(fileName.c_str(), "wb");
        if (!fOut) {
            SkDebugf("could not open output file %s\n", fileName.c_str());
            return false;
        }
        RootDefinition* root =
                bmhParser.fClassMap.end() == bmhParser.fClassMap.find(skClassName) ?
                nullptr : &bmhParser.fClassMap[skClassName];
        fBmhParser = &bmhParser;
        if (root) {
            fRootTopic = root->fParent;
            root->clearVisited();
        } else {
            SkASSERT("Sk" == skClassName.substr(0, 2));
            string topicName = skClassName.substr(2);
            auto topicIter = bmhParser.fTopicMap.find(topicName);
            SkASSERT(bmhParser.fTopicMap.end() != topicIter);
            fRootTopic = topicIter->second->asRoot();
            fFirstWrite = true;   // write file information after includes
        }
        fFileName = includeMapper.second.fFileName;
        this->setStartBack(includeMapper.second.fContentStart, &includeMapper.second);
        fEnd = includeMapper.second.fContentEnd;
        fAnonymousEnumCount = 1;
        this->writeHeader(includeMapper);
        allPassed &= this->populate(&includeMapper.second, nullptr, root);
        this->writeBlock((int) (fEnd - fStart), fStart);
#if 0
        if (fIndentStack.size() > 0) {
            this->indentOut();
        }
        SkASSERT(!fIndent);
#else
        fIndent = 0;
#endif
        this->lfcr();
        this->writePending();
        fclose(fOut);
        fflush(fOut);
        size_t slash = fFileName.find_last_of('/');
        if (string::npos == slash) {
            slash = 0;
        }
        size_t back = fFileName.find_last_of('\\');
        if (string::npos == back) {
            back = 0;
        }
        string dir = fFileName.substr(0, SkTMax(slash, back) + 1);
        string readname = dir + fileName;
        if (ParserCommon::WrittenFileDiffers(fileName, readname)) {
            SkDebugf("wrote updated %s\n", fileName.c_str());
        } else {
            remove(fileName.c_str());
        }
    }
    return allPassed;
}

string IncludeWriter::resolveMethod(const char* start, const char* end, bool first) {
    string methodname(start, end - start);
    if (string::npos != methodname.find("()")) {
        return "";
    }
    string substitute;
    auto rootDefIter = fBmhParser->fMethodMap.find(methodname);
    if (fBmhParser->fMethodMap.end() != rootDefIter) {
        substitute = methodname + "()";
    } else {
        RootDefinition* parent = nullptr;
        for (auto candidate : fRootTopic->fChildren) {
            if (MarkType::kClass == candidate->fMarkType
                    || MarkType::kStruct == candidate->fMarkType) {
                parent = candidate->asRoot();
                break;
            }
        }
        if (parent) {
            auto defRef = parent->find(parent->fName + "::" + methodname,
                    RootDefinition::AllowParens::kNo);
            if (defRef && MarkType::kMethod == defRef->fMarkType) {
                substitute = methodname + "()";
            } else {
                auto defineIter = fBmhParser->fDefineMap.find(methodname);
                if (fBmhParser->fDefineMap.end() != defineIter) {
                    const RootDefinition& defineDef = defineIter->second;
                    auto codeIter = std::find_if(defineDef.fChildren.begin(),
                            defineDef.fChildren.end(),
                            [](Definition* child){ return MarkType::kCode == child->fMarkType; } );
                    if (defineDef.fChildren.end() != codeIter) {
                        const Definition* codeDef = *codeIter;
                        string codeContents(codeDef->fContentStart, codeDef->length());
                        size_t namePos = codeContents.find(methodname);
                        if (string::npos != namePos) {
                            size_t parenPos = namePos + methodname.length();
                            if (parenPos < codeContents.length() && '(' == codeContents[parenPos]) {
                                substitute = methodname + "()";
                            }
                        }
                    }
                }
            }
        }
    }
    if (fMethodDef && methodname == fMethodDef->fName) {
        TextParser report(fBmhMethod);
        report.reportError("method should not include references to itself");
        return "";
    }
    if (fBmhMethod) {
        for (auto child : fBmhMethod->fChildren) {
            if (MarkType::kParam != child->fMarkType) {
                continue;
            }
            if (methodname == child->fName) {
                return "";
            }
        }
    }
    return substitute;
}

string IncludeWriter::resolveAlias(const Definition* def) {
    for (auto child : def->fChildren) {
        if (MarkType::kSubstitute == child->fMarkType) {
            return string(child->fContentStart, (int) (child->fContentEnd - child->fContentStart));
        }
        if (MarkType::kAlias == child->fMarkType && def->fName == child->fName) {
            return this->resolveAlias(child);
        }
    }
    return "";
}

string IncludeWriter::resolveRef(const char* start, const char* end, bool first,
        RefType* refType) {
        // look up Xxx_Xxx
    string undername(start, end - start);
    for (const auto& external : fBmhParser->fExternals) {
        if (external.fName == undername) {
            *refType = RefType::kExternal;
            return external.fName;
        }
    }
    *refType = RefType::kNormal;
    SkASSERT(string::npos == undername.find(' '));
    const Definition* rootDef = nullptr;
    string substitute;
    {
        auto rootDefIter = fBmhParser->fTopicMap.find(undername);
        if (fBmhParser->fTopicMap.end() != rootDefIter) {
            rootDef = rootDefIter->second;
        } else {
            string prefixedName = fRootTopic->fName + '_' + undername;
            rootDefIter = fBmhParser->fTopicMap.find(prefixedName);
            if (fBmhParser->fTopicMap.end() != rootDefIter) {
                rootDef = rootDefIter->second;
            } else if (fBmhStructDef) {
                string localPrefix = fBmhStructDef->fFiddle + '_' + undername;
                rootDefIter = fBmhParser->fTopicMap.find(localPrefix);
                if (fBmhParser->fTopicMap.end() != rootDefIter) {
                    rootDef = rootDefIter->second;
                }
                if (!rootDef) {
                    size_t doubleColon = fBmhStructDef->fName.rfind("::");
                    if (string::npos != doubleColon && undername
                            == fBmhStructDef->fName.substr(doubleColon + 2)) {
                        substitute = fBmhStructDef->fName;
                    }
                }
            }
            if (!rootDef && fEnumDef && "Sk" + prefixedName == fEnumDef->fFiddle) {
                rootDef = fEnumDef;
            }
            if (!rootDef && !substitute.length()) {
                auto aliasIter = fBmhParser->fAliasMap.find(undername);
                if (fBmhParser->fAliasMap.end() != aliasIter) {
                    rootDef = aliasIter->second;
                } else if (fInEnum && fEnumDef && this->findEnumSubtopic(undername, &rootDef)) {
                    ;
                } else if (!first) {
                    this->fChar = start;
                    this->fLine = start;
                    this->fEnd = end;
                    this->reportError("reference unfound");
                    return "";
                }
            }
        }
    }
    if (rootDef) {
        MarkType rootType = rootDef->fMarkType;
        if (MarkType::kSubtopic == rootType || MarkType::kTopic == rootType
                || MarkType::kAlias == rootType) {
            substitute = this->resolveAlias(rootDef);
        }
        if (!substitute.length()) {
            string match = rootDef->fName;
            size_t index;
            while (string::npos != (index = match.find('_'))) {
                match.erase(index, 1);
            }
            string skmatch = "Sk" + match;
            auto parent = MarkType::kAlias == rootType ? rootDef->fParent : rootDef;
            for (auto child : parent->fChildren) {
                // there may be more than one
                // prefer the one mostly closely matching in text
                if ((MarkType::kClass == child->fMarkType ||
                    MarkType::kStruct == child->fMarkType ||
                    MarkType::kTypedef == child->fMarkType ||
                    (MarkType::kEnum == child->fMarkType && !child->fAnonymous) ||
                    MarkType::kEnumClass == child->fMarkType) && (match == child->fName ||
                    skmatch == child->fName)) {
                    substitute = child->fName;
                    break;
                }
            }
        }
        if (!substitute.length()) {
            for (auto child : rootDef->fChildren) {
                if (MarkType::kSubstitute == child->fMarkType) {
                    substitute = string(child->fContentStart, child->length());
                    break;
                }
                // there may be more than one
                // if so, it's a bug since it's unknown which is the right one
                if (MarkType::kClass == child->fMarkType ||
                        MarkType::kStruct == child->fMarkType ||
                        (MarkType::kEnum == child->fMarkType && !child->fAnonymous) ||
                        MarkType::kEnumClass == child->fMarkType) {
                    SkASSERT("" == substitute);
                    substitute = child->fName;
                    if (MarkType::kEnum == child->fMarkType) {
                        size_t parentClassEnd = substitute.find("::");
                        SkASSERT(string::npos != parentClassEnd);
                        string subEnd = substitute.substr(parentClassEnd + 2);
                        if (fInEnum) {
                            substitute = subEnd;
                        }
                        if (subEnd == undername) {
                            break;
                        }
                    }
                }
            }
        }
        if (!substitute.length()) {
            const Definition* parent = rootDef;
            do {
                parent = parent->fParent;
            } while (parent && (MarkType::kSubtopic == parent->fMarkType
                        || MarkType::kTopic == parent->fMarkType));
            if (parent) {
                if (MarkType::kClass == parent->fMarkType ||
                        MarkType::kStruct == parent->fMarkType ||
                        (MarkType::kEnum == parent->fMarkType && !parent->fAnonymous) ||
                        MarkType::kEnumClass == parent->fMarkType) {
                    if (parent->fParent != fRootTopic) {
                        substitute = parent->fName;
                        substitute += ' ';
                        substitute += ParserCommon::ConvertRef(rootDef->fName, false);
                    } else {
                        size_t underpos = undername.find('_');
                        if (string::npos != underpos) {
                            string parentName = undername.substr(0, underpos);
                            string skName = "Sk" + parentName;
                            if (skName == parent->fName) {
                                SkASSERT(start >= fLastDescription->fContentStart);
                                string lastDescription = string(fLastDescription->fContentStart,
                                        (int) (start - fLastDescription->fContentStart));
                                size_t lineStart = lastDescription.rfind('\n');
                                SkASSERT(string::npos != lineStart);
                                fLine = fLastDescription->fContentStart + lineStart + 1;
                                fChar = start;
                                fEnd = end;
                                return this->reportError<string>("remove underline");
                            }
                        }
                        substitute += ParserCommon::ConvertRef(undername, first);
                    }
                }
            }
        }
    }
    // Ensure first word after period is capitalized if substitute is lower cased.
    if (first && isupper(start[0]) && substitute.length() > 0 && islower(substitute[0])) {
        substitute[0] = start[0];
    }
    return substitute;
}

int IncludeWriter::lookupMethod(const PunctuationState punctuation, const Word word,
        const int lastSpace, const int run, int lastWrite, const char* data,
        bool hasIndirection) {
    int wordStart = lastSpace;
    while (' ' >= data[wordStart]) {
        ++wordStart;
    }
    const int wordEnd = PunctuationState::kDelimiter == punctuation ||
            PunctuationState::kParen == punctuation ||
            PunctuationState::kPeriod == punctuation ? run - 1 : run;
    string temp;
    if (hasIndirection && '(' != data[wordEnd - 1] && ')' != data[wordEnd - 1]) {
        // FIXME: hard-coded to assume a.b or a->b is a.b() or a->b().
        // need to check class a for member b to see if this is so
        TextParser parser(fFileName, &data[wordStart], &data[wordEnd], fLineCount);
        const char* indirection = parser.anyOf(".>");
        if (&data[wordEnd] <= &indirection[2] || 'f' != indirection[1] ||
                !isupper(indirection[2])) {
            temp = string(&data[wordStart], wordEnd - wordStart) + "()";
        }
    } else {
        temp = this->resolveMethod(&data[wordStart], &data[wordEnd], Word::kFirst == word);
    }
    if (temp.length()) {
        if (wordStart > lastWrite) {
            SkASSERT(data[wordStart - 1] >= ' ');
            if (' ' == data[lastWrite]) {
                this->writeSpace();
            }
            this->firstBlockTrim(wordStart - lastWrite, &data[lastWrite]);
            if (' ' == data[wordStart - 1]) {
                this->writeSpace();
            }
        }
        SkASSERT(temp[temp.length() - 1] > ' ');
        this->writeString(temp.c_str());
        lastWrite = wordEnd;
    }
    return lastWrite;
}

int IncludeWriter::lookupReference(const PunctuationState punctuation, const Word word,
        const int start, const int run, int lastWrite, const char last, const char* data) {
    const int end = PunctuationState::kDelimiter == punctuation ||
            PunctuationState::kParen == punctuation ||
            PunctuationState::kPeriod == punctuation ? run - 1 : run;
    RefType refType = RefType::kUndefined;
    string resolved = string(&data[start], (size_t) (end - start));
    string temp = this->resolveRef(&data[start], &data[end], Word::kFirst == word, &refType);
    if (!temp.length()) {
        if (Word::kFirst != word && '_' != last) {
            temp = ParserCommon::ConvertRef(resolved, false);
        }
    }
    if (temp.length()) {
        if (start > lastWrite) {
            SkASSERT(data[start - 1] >= ' ');
            if (' ' == data[lastWrite]) {
                this->writeSpace();
            }
            this->firstBlockTrim(start - lastWrite, &data[lastWrite]);
            if (' ' == data[start - 1]) {
                this->writeSpace();
            }
        }
        SkASSERT(temp[temp.length() - 1] > ' ');
        this->writeString(temp.c_str());
        lastWrite = end;
    }
    return lastWrite;
}

/* returns true if rewriteBlock wrote linefeeds */
IncludeWriter::Wrote IncludeWriter::rewriteBlock(int size, const char* data, Phrase phrase) {
    bool wroteLineFeeds = false;
    while (size > 0 && data[0] <= ' ') {
        --size;
        ++data;
    }
    while (size > 0 && data[size - 1] <= ' ') {
        --size;
    }
    if (0 == size) {
        return Wrote::kNone;
    }
    if (fReturnOnWrite) {
        return Wrote::kChars;
    }
    int run = 0;
    Word word = Word::kStart;
    PunctuationState punctuation = Phrase::kNo == phrase ?
            PunctuationState::kStart : PunctuationState::kSpace;
    int start = 0;
    int lastWrite = 0;
    int lineFeeds = 0;
    int lastPrintable = 0;
    int lastSpace = -1;
    char c = 0;
    char last = 0;
    bool embeddedIndirection = false;
    bool embeddedSymbol = false;
    bool hasLower = false;
    bool hasUpper = false;
    bool hasIndirection = false;
    bool hasSymbol = false;
    while (run < size) {
        last = c;
        c = data[run];
        SkASSERT(' ' <= c || '\n' == c);
        if (lineFeeds && ' ' < c) {
            if (lastPrintable >= lastWrite) {
                if (' ' == data[lastWrite]) {
                    this->writeSpace();
                    lastWrite++;
                }
                this->writeBlock(lastPrintable - lastWrite + 1, &data[lastWrite]);
            }
            if (lineFeeds > 1) {
                this->lf(2);
            }
            this->lfcr(); // defer the indent until non-whitespace is seen
            lastWrite = run;
            lineFeeds = 0;
        }
        if (' ' < c) {
            lastPrintable = run;
        }
        switch (c) {
            case '\n':
                ++lineFeeds;
                wroteLineFeeds = true;
            case ' ':
                switch (word) {
                    case Word::kStart:
                        break;
                    case Word::kUnderline:
                    case Word::kCap:
                    case Word::kFirst:
                        if (!hasLower) {
                            break;
                        }
                        lastWrite = this->lookupReference(punctuation, word, start, run,
                                lastWrite, last, data);
                        break;
                    case Word::kMixed:
                        if (hasUpper && hasLower && !hasSymbol && lastSpace > 0) {
                            lastWrite = this->lookupMethod(punctuation, word, lastSpace, run,
                                    lastWrite, data, hasIndirection);
                        }
                        break;
                    default:
                        SkASSERT(0);
                }
                punctuation = PunctuationState::kPeriod == punctuation ||
                        (PunctuationState::kStart == punctuation && ' ' >= last) ?
                        PunctuationState::kStart : PunctuationState::kSpace;
                word = Word::kStart;
                embeddedIndirection = false;
                embeddedSymbol = false;
                hasLower = false;
                hasUpper = false;
                hasIndirection = false;
                hasSymbol = false;
                lastSpace = run;
                break;
            case '.': case ',': case ';': case ':': case ')':
                switch (word) {
                    case Word::kStart:
                        punctuation = PunctuationState::kDelimiter;
                    case Word::kCap:
                    case Word::kFirst:
                    case Word::kUnderline:
                    case Word::kMixed:
                        if (PunctuationState::kDelimiter == punctuation ||
                                PunctuationState::kPeriod == punctuation) {
                            word = Word::kMixed;
                        }
                        punctuation = '.' == c ? PunctuationState::kPeriod :
                                PunctuationState::kDelimiter;
                        break;
                    default:
                        SkASSERT(0);
                }
                ('.' == c ? embeddedIndirection : embeddedSymbol) = true;
                break;
            case '>':
                if ('-' == last) {
                    embeddedIndirection = true;
                    break;
                }
            case '\'': // possessive apostrophe isn't treated as delimiting punctation
            case '\"': // quote is passed straight through
            case '=':
            case '!':  // assumed not to be punctuation, but a programming symbol
            case '&': case '<': case '{': case '}': case '/': case '*': case '[': case ']':
                word = Word::kMixed;
                embeddedSymbol = true;
                break;
            case '(':
                if (' ' == last) {
                    punctuation = PunctuationState::kParen;
                } else {
                    word = Word::kMixed;
                }
                embeddedSymbol = true;
                break;
            case '_':
                switch (word) {
                    case Word::kStart:
                        word = Word::kMixed;
                        break;
                    case Word::kCap:
                    case Word::kFirst:
                    case Word::kUnderline:
                        word = Word::kUnderline;
                        break;
                    case Word::kMixed:
                        break;
                    default:
                        SkASSERT(0);
                }
                hasSymbol |= embeddedSymbol;
                break;
            case '+':
                // hackery to allow C++
                SkASSERT('C' == last || '+' == last);  // FIXME: don't allow + outside of #Formula
                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':
                switch (word) {
                    case Word::kStart:
                        word = PunctuationState::kStart == punctuation ? Word::kFirst : Word::kCap;
                        start = run;
                        break;
                    case Word::kCap:
                    case Word::kFirst:
                        if (!isupper(last) && '~' != last) {
                            word = Word::kMixed;
                        }
                        break;
                    case Word::kUnderline:
                        // some word in Xxx_XXX_Xxx can be all upper, but all can't: XXX_XXX
                        if ('_' != last && !isupper(last)) {
                            word = Word::kMixed;
                        }
                        break;
                    case Word::kMixed:
                        break;
                    default:
                        SkASSERT(0);
                }
                hasUpper = true;
                if (PunctuationState::kPeriod == punctuation ||
                        PunctuationState::kDelimiter == punctuation) {
                    word = Word::kMixed;
                }
                hasIndirection |= embeddedIndirection;
                hasSymbol |= embeddedSymbol;
                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 '0': case '1': case '2': case '3': case '4':
            case '5': case '6': case '7': case '8': case '9':
            case '%':  // to do : ensure that preceding is a number
            case '-':
                switch (word) {
                    case Word::kStart:
                        word = Word::kMixed;
                        break;
                    case Word::kMixed:
                    case Word::kCap:
                    case Word::kFirst:
                    case Word::kUnderline:
                        break;
                    default:
                        SkASSERT(0);
                }
                hasLower = true;
                punctuation = PunctuationState::kStart;
                hasIndirection |= embeddedIndirection;
                hasSymbol |= embeddedSymbol;
                break;
            case '~':
                SkASSERT(Word::kStart == word);
                word = PunctuationState::kStart == punctuation ? Word::kFirst : Word::kCap;
                start = run;
                hasUpper = true;
                hasIndirection |= embeddedIndirection;
                hasSymbol |= embeddedSymbol;
                break;
            default:
                SkASSERT(0);
        }
        ++run;
    }
    if ((word == Word::kCap || word == Word::kFirst || word == Word::kUnderline) && hasLower) {
        lastWrite = this->lookupReference(punctuation, word, start, run, lastWrite, last, data);
    } else if (word == Word::kMixed && hasUpper && hasLower && !hasSymbol && lastSpace > 0) {
        lastWrite = this->lookupMethod(punctuation, word, lastSpace, run, lastWrite, data,
                hasIndirection && !hasSymbol);
    }
    if (run > lastWrite) {
        if (' ' == data[lastWrite]) {
            this->writeSpace();
        }
        this->writeBlock(run - lastWrite, &data[lastWrite]);
    }
    return wroteLineFeeds ? Wrote::kLF : Wrote::kChars;
}

static string paddedString(int num) {
    auto padded = std::to_string(num);
    padded.insert(0, 2U - std::min(string::size_type(2), padded.length()), '0');
    return padded;
}

bool IncludeWriter::writeHeader(std::pair<const string, Definition>& include) {
    std::chrono::system_clock::time_point now = std::chrono::system_clock::now();
    time_t tt = std::chrono::system_clock::to_time_t(now);
    tm local_tm = *localtime(&tt);

    // find end of copyright header
    fChar = fStart;
    this->skipWhiteSpace();
    if (!this->skipExact(
            "/*\n"
            " * Copyright ")) {
        return this->reportError<bool>("copyright mismatch 1");
    }
    const char* date = fChar;
    this->skipToSpace();
    string yearStr(date, fChar - date);
    int year = stoi(yearStr);
    if (year < 2005 || year > local_tm.tm_year + 1900) {
        return this->reportError<bool>("copyright year out of range");
    }
    this->skipSpace();
    const char android[] = "The Android Open Source Project";
    const char google[] = "Google Inc.";
    if (this->startsWith(android)) {
        this->skipExact(android);
    } else if (!this->skipExact(google)) {
        return this->reportError<bool>("copyright mismatch 2");
    }
    if (!this->skipExact(
            "\n"
            " *\n"
            " * Use of this source code is governed by a BSD-style license that can be\n"
            " * found in the LICENSE file.\n"
            " */\n"
            "\n"
            )) {
        return this->reportError<bool>("copyright mismatch 2");
    }
    this->writeBlock(fChar - fStart, fStart);
    this->lf(2);
    this->writeString("/* Generated by tools/bookmaker from");
    this->writeSpace();
    string includeName = include.first;
    std::replace(includeName.begin(), includeName.end(), '\\', '/');
    this->writeString(includeName);
    this->writeSpace();
    this->writeString("and");
    this->writeSpace();
    string bmhName = fRootTopic->fFileName;
    std::replace(bmhName.begin(), bmhName.end(), '\\', '/');
    this->writeString(bmhName);
    this->lfcr();
    fIndent = 3;
    string dateTimeStr = std::to_string(local_tm.tm_year + 1900) + "-"
            + paddedString(local_tm.tm_mon + 1) + "-"
            + paddedString(local_tm.tm_mday) + " "
            + paddedString(local_tm.tm_hour) + ":"
            + paddedString(local_tm.tm_min) + ":"
            + paddedString(local_tm.tm_sec);
    this->writeString("on");
    this->writeSpace();
    this->writeString(dateTimeStr);
    this->writeString(". Additional documentation and examples can be found at:");
    this->lfcr();
    this->writeString("https://skia.org/user/api/");
    size_t bmhPageStart = bmhName.rfind('/');
    size_t bmhPageEnd = bmhName.rfind('.');
    if (string::npos == bmhPageStart || string::npos == bmhPageEnd) {
        return this->reportError<bool>("badly formed bmh page name");
    }
    ++bmhPageStart;
    string bmhPage = bmhName.substr(bmhPageStart, bmhPageEnd - bmhPageStart);
    this->writeString(bmhPage);
    this->lf(2);
    this->writeString("You may edit either file directly. Structural changes to public interfaces require");
    this->lfcr();
    this->writeString("editing both files. After editing");
    this->writeSpace();
    this->writeString(bmhName);
    this->writeSpace();
    this->writeString(", run:");
    this->lfcr();
    fIndent += 4;
    this->writeString("bookmaker -b docs -i");
    this->writeSpace();
    this->writeString(includeName);
    this->writeSpace();
    this->writeString("-p");
    this->lfcr();
    fIndent -= 4;
    this->writeString("to create an updated version of this file.");
    this->lfcr();
    fIndent = 1;
    this->writeString("*/");
    this->lf(2);
    fIndent = 0;
    if (this->startsWith("/* Generated by tools/bookmaker from")) {
        this->skipToEndBracket("*/");
        if (!this->skipExact("*/\n\n")) {
            return this->reportError<bool>("malformed generated comment");
        }
    }
    fStart = fChar;

    return true;
}
