refactor bookmaker

mostly create include files with minimum
content

TBR=caryclark@google.com

Bug: skia:
Change-Id: I3db0f913cc108bd5ef8ec6c3b229eaccc3f25198
Reviewed-on: https://skia-review.googlesource.com/c/167302
Commit-Queue: Cary Clark <caryclark@skia.org>
Auto-Submit: Cary Clark <caryclark@skia.org>
Reviewed-by: Cary Clark <caryclark@skia.org>
diff --git a/tools/bookmaker/definition.h b/tools/bookmaker/definition.h
new file mode 100644
index 0000000..632135b
--- /dev/null
+++ b/tools/bookmaker/definition.h
@@ -0,0 +1,326 @@
+/*
+ * Copyright 2018 Google Inc.
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#ifndef definition_DEFINED
+#define definition_DEFINED
+
+#include "textParser.h"
+
+class RootDefinition;
+class TextParser;
+
+class Definition : public NonAssignable {
+public:
+    enum Type {
+        kNone,
+        kWord,
+        kMark,
+        kKeyWord,
+        kBracket,
+        kPunctuation,
+        kFileType,
+    };
+
+    enum class MethodType {
+        kNone,
+        kConstructor,
+        kDestructor,
+        kOperator,
+    };
+
+    enum class Operator {
+        kUnknown,
+        kAdd,
+        kAddTo,
+        kArray,
+        kCast,
+        kCopy,
+        kDelete,
+        kDereference,
+        kEqual,
+        kMinus,
+        kMove,
+        kMultiply,
+        kMultiplyBy,
+        kNew,
+        kNotEqual,
+        kSubtract,
+        kSubtractFrom,
+    };
+
+    enum class Format {
+        kIncludeReturn,
+        kOmitReturn,
+    };
+
+    enum class Details {
+        kNone,
+        kSoonToBe_Deprecated,
+        kTestingOnly_Experiment,
+        kDoNotUse_Experiment,
+        kNotReady_Experiment,
+    };
+
+    enum class DetailsType {
+        kPhrase,
+        kSentence,
+    };
+
+    Definition() {}
+
+    Definition(const char* start, const char* end, int line, Definition* parent, char mc)
+        : fStart(start)
+        , fContentStart(start)
+        , fContentEnd(end)
+        , fParent(parent)
+        , fLineCount(line)
+        , fType(Type::kWord)
+        , fMC(mc) {
+        if (parent) {
+            SkASSERT(parent->fFileName.length() > 0);
+            fFileName = parent->fFileName;
+        }
+        this->setParentIndex();
+    }
+
+    Definition(MarkType markType, const char* start, int line, Definition* parent, char mc)
+        : Definition(markType, start, nullptr, line, parent, mc) {
+    }
+
+    Definition(MarkType markType, const char* start, const char* end, int line, Definition* parent, char mc)
+        : Definition(start, end, line, parent, mc) {
+        fMarkType = markType;
+        fType = Type::kMark;
+    }
+
+    Definition(Bracket bracket, const char* start, int lineCount, Definition* parent, char mc)
+        : Definition(start, nullptr, lineCount, parent, mc) {
+        fBracket = bracket;
+        fType = Type::kBracket;
+    }
+
+    Definition(KeyWord keyWord, const char* start, const char* end, int lineCount,
+            Definition* parent, char mc)
+        : Definition(start, end, lineCount, parent, mc) {
+        fKeyWord = keyWord;
+        fType = Type::kKeyWord;
+    }
+
+    Definition(Punctuation punctuation, const char* start, int lineCount, Definition* parent, char mc)
+        : Definition(start, nullptr, lineCount, parent, mc) {
+        fPunctuation = punctuation;
+        fType = Type::kPunctuation;
+    }
+
+    virtual ~Definition() {}
+
+    virtual RootDefinition* asRoot() { SkASSERT(0); return nullptr; }
+    bool boilerplateIfDef();
+
+    bool boilerplateEndIf() {
+        return true;
+    }
+
+    bool checkMethod() const;
+    bool crossCheck2(const Definition& includeToken) const;
+    bool crossCheck(const Definition& includeToken) const;
+    bool crossCheckInside(const char* start, const char* end, const Definition& includeToken) const;
+
+    Definition* csParent() {
+        Definition* test = fParent;
+        while (test) {
+            if (MarkType::kStruct == test->fMarkType || MarkType::kClass == test->fMarkType) {
+                return test;
+            }
+            test = test->fParent;
+        }
+        return nullptr;
+    }
+
+    string fiddleName() const;
+    string fileName() const;
+    const Definition* findClone(string match) const;
+    string formatFunction(Format format) const;
+    const Definition* hasChild(MarkType markType) const;
+    bool hasMatch(string name) const;
+    Definition* hasParam(string ref);
+    string incompleteMessage(DetailsType ) const;
+    bool isClone() const { return fClone; }
+
+    const Definition* iRootParent() const {
+        const Definition* test = fParent;
+        while (test) {
+            if (KeyWord::kClass == test->fKeyWord || KeyWord::kStruct == test->fKeyWord) {
+                return test;
+            }
+            test = test->fParent;
+        }
+        return nullptr;
+    }
+
+    virtual bool isRoot() const { return false; }
+    bool isStructOrClass() const;
+
+    int length() const {
+        return (int) (fContentEnd - fContentStart);
+    }
+
+    const char* methodEnd() const;
+    bool methodHasReturn(string name, TextParser* methodParser) const;
+    string methodName() const;
+    bool nextMethodParam(TextParser* methodParser, const char** nextEndPtr,
+                         string* paramName) const;
+    static string NormalizedName(string name);
+    bool paramsMatch(string fullRef, string name) const;
+    bool parseOperator(size_t doubleColons, string& result);
+
+    string printableName() const {
+        string result(fName);
+        std::replace(result.begin(), result.end(), '_', ' ');
+        return result;
+    }
+
+    template <typename T> T reportError(const char* errorStr) const {
+        TextParser tp(this);
+        tp.reportError(errorStr);
+        return T();
+    }
+
+    virtual RootDefinition* rootParent() { SkASSERT(0); return nullptr; }
+    virtual const RootDefinition* rootParent() const { SkASSERT(0); return nullptr; }
+    void setCanonicalFiddle();
+
+    void setParentIndex() {
+        fParentIndex = fParent ? (int) fParent->fTokens.size() : -1;
+    }
+
+    string simpleName() {
+        size_t doubleColon = fName.rfind("::");
+        return string::npos == doubleColon ? fName : fName.substr(doubleColon + 2);
+    }
+
+    const Definition* subtopicParent() const {
+        Definition* test = fParent;
+        while (test) {
+            if (MarkType::kTopic == test->fMarkType || MarkType::kSubtopic == test->fMarkType) {
+                return test;
+            }
+            test = test->fParent;
+        }
+        return nullptr;
+    }
+
+    const Definition* topicParent() const {
+        Definition* test = fParent;
+        while (test) {
+            if (MarkType::kTopic == test->fMarkType) {
+                return test;
+            }
+            test = test->fParent;
+        }
+        return nullptr;
+    }
+
+    void trimEnd();
+
+    string fText;  // if text is constructed instead of in a file, it's put here
+    const char* fStart = nullptr;  // .. in original text file, or the start of fText
+    const char* fContentStart;  // start past optional markup name
+    string fName;
+    string fFiddle;  // if its a constructor or operator, fiddle name goes here
+    string fCode;  // suitable for autogeneration of #Code blocks in bmh
+    const char* fContentEnd = nullptr;  // the end of the contained text
+    const char* fTerminator = nullptr;  // the end of the markup, normally ##\n or \n
+    Definition* fParent = nullptr;
+    list<Definition> fTokens;
+    vector<Definition*> fChildren;
+    string fHash;  // generated by fiddle
+    string fFileName;
+    mutable string fWrapper; // used by Example to wrap into proper function
+    size_t fLineCount = 0;
+    int fParentIndex = 0;
+    MarkType fMarkType = MarkType::kNone;
+    KeyWord fKeyWord = KeyWord::kNone;
+    Bracket fBracket = Bracket::kNone;
+    Punctuation fPunctuation = Punctuation::kNone;
+    MethodType fMethodType = MethodType::kNone;
+    Operator fOperator = Operator::kUnknown;
+    Type fType = Type::kNone;
+    char fMC = '#';
+    bool fClone = false;
+    bool fCloned = false;
+    bool fDeprecated = false;
+    bool fOperatorConst = false;
+    bool fPrivate = false;
+    Details fDetails = Details::kNone;
+    bool fMemberStart = false;
+    bool fAnonymous = false;
+    mutable bool fVisited = false;
+};
+
+class RootDefinition : public Definition {
+public:
+    enum class AllowParens {
+        kNo,
+        kYes,
+    };
+
+    struct SubtopicContents {
+        SubtopicContents()
+            : fShowClones(false) {
+        }
+
+        vector<Definition*> fMembers;
+        bool fShowClones;
+    };
+
+    RootDefinition() {
+    }
+
+    RootDefinition(MarkType markType, const char* start, int line, Definition* parent, char mc)
+            : Definition(markType, start, line, parent, mc) {
+        if (MarkType::kSubtopic != markType && MarkType::kTopic != markType) {
+            if (parent) {
+                fNames.fName = parent->fName;
+                fNames.fParent = &parent->asRoot()->fNames;
+            }
+        }
+    }
+
+    RootDefinition(MarkType markType, const char* start, const char* end, int line,
+            Definition* parent, char mc) : Definition(markType, start, end, line, parent, mc) {
+    }
+
+    ~RootDefinition() override {
+        for (auto& iter : fBranches) {
+            delete iter.second;
+        }
+    }
+
+    RootDefinition* asRoot() override { return this; }
+    void clearVisited();
+    bool dumpUnVisited();
+    Definition* find(string ref, AllowParens );
+    bool isRoot() const override { return true; }
+
+    SubtopicContents& populator(const char* key) {
+        return fPopulators[key];
+    }
+
+    RootDefinition* rootParent() override { return fRootParent; }
+    const RootDefinition* rootParent() const override { return fRootParent; }
+    void setRootParent(RootDefinition* rootParent) { fRootParent = rootParent; }
+
+    unordered_map<string, RootDefinition*> fBranches;
+    unordered_map<string, Definition> fLeaves;
+    unordered_map<string, SubtopicContents> fPopulators;
+    NameMap fNames;
+private:
+    RootDefinition* fRootParent = nullptr;
+};
+
+#endif