// Copyright (C) 2006 Google Inc.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
package prettify.parser;

import prettify.lang.Lang;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import prettify.lang.LangAppollo;
import prettify.lang.LangClj;
import prettify.lang.LangCss;
import prettify.lang.LangDart;
import prettify.lang.LangErlang;
import prettify.lang.LangGo;
import prettify.lang.LangHs;
import prettify.lang.LangLisp;
import prettify.lang.LangLua;
import prettify.lang.LangMl;
import prettify.lang.LangMumps;
import prettify.lang.LangN;
import prettify.lang.LangR;
import prettify.lang.LangRd;
import prettify.lang.LangScala;
import prettify.lang.LangSql;
import prettify.lang.LangTcl;
import prettify.lang.LangTex;
import prettify.lang.LangVb;
import prettify.lang.LangVhdl;
import prettify.lang.LangWiki;
import prettify.lang.LangXq;
import prettify.lang.LangYaml;

/**
 * This is similar to the prettify.js in JavaScript Prettify.
 * 
 * All comments are adapted from the JavaScript Prettify.
 * 
 * <p>
 * Some functions for browser-side pretty printing of code contained in html.
 * </p>
 *
 * <p>
 * For a fairly comprehensive set of languages see the
 * <a href="http://google-code-prettify.googlecode.com/svn/trunk/README.html#langs">README</a>
 * file that came with this source.  At a minimum, the lexer should work on a
 * number of languages including C and friends, Java, Python, Bash, SQL, HTML,
 * XML, CSS, Javascript, and Makefiles.  It works passably on Ruby, PHP and Awk
 * and a subset of Perl, but, because of commenting conventions, doesn't work on
 * Smalltalk, Lisp-like, or CAML-like languages without an explicit lang class.
 * <p>
 * Usage: <ol>
 * <li> include this source file in an html page via
 *   {@code <script type="text/javascript" src="/path/to/prettify.js"></script>}
 * <li> define style rules.  See the example page for examples.
 * <li> mark the {@code <pre>} and {@code <code>} tags in your source with
 *    {@code class=prettyprint.}
 *    You can also use the (html deprecated) {@code <xmp>} tag, but the pretty
 *    printer needs to do more substantial DOM manipulations to support that, so
 *    some css styles may not be preserved.
 * </ol>
 * That's it.  I wanted to keep the API as simple as possible, so there's no
 * need to specify which language the code is in, but if you wish, you can add
 * another class to the {@code <pre>} or {@code <code>} element to specify the
 * language, as in {@code <pre class="prettyprint lang-java">}.  Any class that
 * starts with "lang-" followed by a file extension, specifies the file type.
 * See the "lang-*.js" files in this directory for code that implements
 * per-language file handlers.
 * <p>
 * Change log:<br>
 * cbeust, 2006/08/22
 * <blockquote>
 *   Java annotations (start with "@") are now captured as literals ("lit")
 * </blockquote>
 */
public class Prettify {

  private static final Logger LOG = Logger.getLogger(Prettify.class.getName());
  // Keyword lists for various languages.
  public static final String FLOW_CONTROL_KEYWORDS = "break,continue,do,else,for,if,return,while";
  public static final String C_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "auto,case,char,const,default,"
          + "double,enum,extern,float,goto,inline,int,long,register,short,signed,"
          + "sizeof,static,struct,switch,typedef,union,unsigned,void,volatile";
  public static final String COMMON_KEYWORDS = C_KEYWORDS + "," + "catch,class,delete,false,import,"
          + "new,operator,private,protected,public,this,throw,true,try,typeof";
  public static final String CPP_KEYWORDS = COMMON_KEYWORDS + "," + "alignof,align_union,asm,axiom,bool,"
          + "concept,concept_map,const_cast,constexpr,decltype,"
          + "dynamic_cast,explicit,export,friend,generic,late_check,"
          + "mutable,namespace,nullptr,reinterpret_cast,static_assert,static_cast,"
          + "template,typeid,typename,using,virtual,where";
  public static final String JAVA_KEYWORDS = COMMON_KEYWORDS + ","
          + "abstract,assert,boolean,byte,extends,final,finally,implements,import,"
          + "instanceof,interface,null,native,package,strictfp,super,synchronized,"
          + "throws,transient";
  public static final String CSHARP_KEYWORDS = JAVA_KEYWORDS + ","
          + "as,base,by,checked,decimal,delegate,descending,dynamic,event,"
          + "fixed,foreach,from,group,implicit,in,internal,into,is,let,"
          + "lock,object,out,override,orderby,params,partial,readonly,ref,sbyte,"
          + "sealed,stackalloc,string,select,uint,ulong,unchecked,unsafe,ushort,"
          + "var,virtual,where";
  public static final String COFFEE_KEYWORDS = "all,and,by,catch,class,else,extends,false,finally,"
          + "for,if,in,is,isnt,loop,new,no,not,null,of,off,on,or,return,super,then,"
          + "throw,true,try,unless,until,when,while,yes";
  public static final String JSCRIPT_KEYWORDS = COMMON_KEYWORDS + ","
          + "debugger,eval,export,function,get,null,set,undefined,var,with,"
          + "Infinity,NaN";
  public static final String PERL_KEYWORDS = "caller,delete,die,do,dump,elsif,eval,exit,foreach,for,"
          + "goto,if,import,last,local,my,next,no,our,print,package,redo,require,"
          + "sub,undef,unless,until,use,wantarray,while,BEGIN,END";
  public static final String PYTHON_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "and,as,assert,class,def,del,"
          + "elif,except,exec,finally,from,global,import,in,is,lambda,"
          + "nonlocal,not,or,pass,print,raise,try,with,yield,"
          + "False,True,None";
  public static final String RUBY_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "alias,and,begin,case,class,"
          + "def,defined,elsif,end,ensure,false,in,module,next,nil,not,or,redo,"
          + "rescue,retry,self,super,then,true,undef,unless,until,when,yield,"
          + "BEGIN,END";
  public static final String SH_KEYWORDS = FLOW_CONTROL_KEYWORDS + "," + "case,done,elif,esac,eval,fi,"
          + "function,in,local,set,then,until";
  public static final String ALL_KEYWORDS = CPP_KEYWORDS + "," + CSHARP_KEYWORDS + "," + JSCRIPT_KEYWORDS + "," + PERL_KEYWORDS + ","
          + PYTHON_KEYWORDS + "," + RUBY_KEYWORDS + "," + SH_KEYWORDS;
  public static final Pattern C_TYPES = Pattern.compile("^(DIR|FILE|vector|(de|priority_)?queue|list|stack|(const_)?iterator|(multi)?(set|map)|bitset|u?(int|float)\\d*)\\b");
  // token style names.  correspond to css classes
  /**
   * token style for a string literal
   */
  public static final String PR_STRING = "str";
  /**
   * token style for a keyword
   */
  public static final String PR_KEYWORD = "kwd";
  /**
   * token style for a comment
   */
  public static final String PR_COMMENT = "com";
  /**
   * token style for a type
   */
  public static final String PR_TYPE = "typ";
  /**
   * token style for a literal value.  e.g. 1, null, true.
   */
  public static final String PR_LITERAL = "lit";
  /**
   * token style for a punctuation string.
   */
  public static final String PR_PUNCTUATION = "pun";
  /**
   * token style for a plain text.
   */
  public static final String PR_PLAIN = "pln";
  /**
   * token style for an sgml tag.
   */
  public static final String PR_TAG = "tag";
  /**
   * token style for a markup declaration such as a DOCTYPE.
   */
  public static final String PR_DECLARATION = "dec";
  /**
   * token style for embedded source.
   */
  public static final String PR_SOURCE = "src";
  /**
   * token style for an sgml attribute name.
   */
  public static final String PR_ATTRIB_NAME = "atn";
  /**
   * token style for an sgml attribute value.
   */
  public static final String PR_ATTRIB_VALUE = "atv";
  /**
   * A class that indicates a section of markup that is not code, e.g. to allow
   * embedding of line numbers within code listings.
   */
  public static final String PR_NOCODE = "nocode";
  /**
   * A set of tokens that can precede a regular expression literal in
   * javascript
   * http://web.archive.org/web/20070717142515/http://www.mozilla.org/js/language/js20/rationale/syntax.html
   * has the full list, but I've removed ones that might be problematic when
   * seen in languages that don't support regular expression literals.
   *
   * <p>Specifically, I've removed any keywords that can't precede a regexp
   * literal in a syntactically legal javascript program, and I've removed the
   * "in" keyword since it's not a keyword in many languages, and might be used
   * as a count of inches.
   *
   * <p>The link above does not accurately describe EcmaScript rules since
   * it fails to distinguish between (a=++/b/i) and (a++/b/i) but it works
   * very well in practice.
   */
  private static final String REGEXP_PRECEDER_PATTERN = "(?:^^\\.?|[+-]|[!=]=?=?|\\#|%=?|&&?=?|\\(|\\*=?|[+\\-]=|->|\\/=?|::?|<<?=?|>>?>?=?|,|;|\\?|@|\\[|~|\\{|\\^\\^?=?|\\|\\|?=?|break|case|continue|delete|do|else|finally|instanceof|return|throw|try|typeof)\\s*";
  // CAVEAT: this does not properly handle the case where a regular
  // expression immediately follows another since a regular expression may
  // have flags for case-sensitivity and the like.  Having regexp tokens
  // adjacent is not valid in any language I'm aware of, so I'm punting.
  // TODO: maybe style special characters inside a regexp as punctuation.

  public Prettify() {
    try {
      Map<String, Object> decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", ALL_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("cStyleComments", true);
      decorateSourceMap.put("multiLineStrings", true);
      decorateSourceMap.put("regexLiterals", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"default-code"}));

      List<List<Object>> shortcutStylePatterns, fallthroughStylePatterns;

      shortcutStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN, Pattern.compile("^[^<?]+")}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_DECLARATION, Pattern.compile("^<!\\w[^>]*(?:>|$)")}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT, Pattern.compile("^<\\!--[\\s\\S]*?(?:-\\->|$)")}));
      // Unescaped content in an unknown language
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-", Pattern.compile("^<\\?([\\s\\S]+?)(?:\\?>|$)")}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-", Pattern.compile("^<%([\\s\\S]+?)(?:%>|$)")}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PUNCTUATION, Pattern.compile("^(?:<[%?]|[%?]>)")}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-", Pattern.compile("^<xmp\\b[^>]*>([\\s\\S]+?)<\\/xmp\\b[^>]*>", Pattern.CASE_INSENSITIVE)}));
      // Unescaped content in javascript.  (Or possibly vbscript).
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^<script\\b[^>]*>([\\s\\S]*?)(<\\/script\\b[^>]*>)", Pattern.CASE_INSENSITIVE)}));
      // Contains unescaped stylesheet content
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^<style\\b[^>]*>([\\s\\S]*?)(<\\/style\\b[^>]*>)", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-in.tag", Pattern.compile("^(<\\/?[a-z][^<>]*>)", Pattern.CASE_INSENSITIVE)}));
      registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"default-markup", "htm", "html", "mxml", "xhtml", "xml", "xsl"}));

      shortcutStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns = new ArrayList<List<Object>>();
      shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN, Pattern.compile("^[\\s]+"), null, " \t\r\n"}));
      shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_ATTRIB_VALUE, Pattern.compile("^(?:\\\"[^\\\"]*\\\"?|\\'[^\\']*\\'?)"), null, "\"'"}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_TAG, Pattern.compile("^^<\\/?[a-z](?:[\\w.:-]*\\w)?|\\/?>$", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_ATTRIB_NAME, Pattern.compile("^(?!style[\\s=]|on)[a-z](?:[\\w:-]*\\w)?", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-uq.val", Pattern.compile("^=\\s*([^>\\'\\\"\\s]*(?:[^>\\'\\\"\\s\\/]|\\/(?=\\s)))", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PUNCTUATION, Pattern.compile("^[=<>\\/]+")}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^on\\w+\\s*=\\s*\\\"([^\\\"]+)\\\"", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^on\\w+\\s*=\\s*\\'([^\\']+)\\'", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-js", Pattern.compile("^on\\w+\\s*=\\s*([^\\\"\\'>\\s]+)", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^style\\s*=\\s*\\\"([^\\\"]+)\\\"", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^style\\s*=\\s*\\'([^\\']+)\\'", Pattern.CASE_INSENSITIVE)}));
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-css", Pattern.compile("^style\\s*=\\s\\*([^\\\"\\'>\\s]+)", Pattern.CASE_INSENSITIVE)}));
      registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"in.tag"}));

      shortcutStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_ATTRIB_VALUE, Pattern.compile("^[\\s\\S]+")}));
      registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"uq.val"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", CPP_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("cStyleComments", true);
      decorateSourceMap.put("types", C_TYPES);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"c", "cc", "cpp", "cxx", "cyc", "m"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", "null,true,false");
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"json"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", CSHARP_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("cStyleComments", true);
      decorateSourceMap.put("verbatimStrings", true);
      decorateSourceMap.put("types", C_TYPES);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"cs"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", JAVA_KEYWORDS);
      decorateSourceMap.put("cStyleComments", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"java"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", SH_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("multiLineStrings", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"bash", "bsh", "csh", "sh"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", PYTHON_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("multiLineStrings", true);
      decorateSourceMap.put("tripleQuotedStrings", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"cv", "py", "python"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", PERL_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("multiLineStrings", true);
      decorateSourceMap.put("regexLiterals", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"perl", "pl", "pm"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", RUBY_KEYWORDS);
      decorateSourceMap.put("hashComments", true);
      decorateSourceMap.put("multiLineStrings", true);
      decorateSourceMap.put("regexLiterals", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"rb", "ruby"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", JSCRIPT_KEYWORDS);
      decorateSourceMap.put("cStyleComments", true);
      decorateSourceMap.put("regexLiterals", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"javascript", "js"}));

      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", COFFEE_KEYWORDS);
      decorateSourceMap.put("hashComments", 3); // ### style block comments
      decorateSourceMap.put("cStyleComments", true);
      decorateSourceMap.put("multilineStrings", true);
      decorateSourceMap.put("tripleQuotedStrings", true);
      decorateSourceMap.put("regexLiterals", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"coffee"}));

      shortcutStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns = new ArrayList<List<Object>>();
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_STRING, Pattern.compile("^[\\s\\S]+")}));
      registerLangHandler(new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns), Arrays.asList(new String[]{"regex"}));

      /**
       * Registers a language handler for Protocol Buffers as described at
       * http://code.google.com/p/protobuf/.
       *
       * Based on the lexical grammar at
       * http://research.microsoft.com/fsharp/manual/spec2.aspx#_Toc202383715
       *
       * @author mikesamuel@gmail.com
       */
      decorateSourceMap = new HashMap<String, Object>();
      decorateSourceMap.put("keywords", "bytes,default,double,enum,extend,extensions,false,"
              + "group,import,max,message,option,"
              + "optional,package,repeated,required,returns,rpc,service,"
              + "syntax,to,true");
      decorateSourceMap.put("types", Pattern.compile("^(bool|(double|s?fixed|[su]?int)(32|64)|float|string)\\b"));
      decorateSourceMap.put("cStyleComments", true);
      registerLangHandler(sourceDecorator(decorateSourceMap), Arrays.asList(new String[]{"proto"}));

      register(LangAppollo.class);
      register(LangClj.class);
      register(LangCss.class);
      register(LangDart.class);
      register(LangErlang.class);
      register(LangGo.class);
      register(LangHs.class);
      register(LangLisp.class);
      register(LangLua.class);
      register(LangMl.class);
      register(LangMumps.class);
      register(LangN.class);
      register(LangR.class);
      register(LangRd.class);
      register(LangScala.class);
      register(LangSql.class);
      register(LangTex.class);
      register(LangVb.class);
      register(LangVhdl.class);
      register(LangTcl.class);
      register(LangWiki.class);
      register(LangXq.class);
      register(LangYaml.class);
    } catch (Exception ex) {
      LOG.log(Level.SEVERE, null, ex);
    }
  }

  /**
   * Apply the given language handler to sourceCode and add the resulting
   * decorations to out.
   * @param basePos the index of sourceCode within the chunk of source
   *    whose decorations are already present on out.
   */
  protected static void appendDecorations(int basePos, String sourceCode, CreateSimpleLexer langHandler, List<Object> out) {
    if (sourceCode == null) {
      throw new NullPointerException("argument 'sourceCode' cannot be null");
    }
    Job job = new Job();
    job.setSourceCode(sourceCode);
    job.setBasePos(basePos);
    langHandler.decorate(job);
    out.addAll(job.getDecorations());
  }

  public class CreateSimpleLexer {

    protected List<List<Object>> fallthroughStylePatterns;
    protected Map<Character, List<Object>> shortcuts = new HashMap<Character, List<Object>>();
    protected Pattern tokenizer;
    protected int nPatterns;

    /** Given triples of [style, pattern, context] returns a lexing function,
     * The lexing function interprets the patterns to find token boundaries and
     * returns a decoration list of the form
     * [index_0, style_0, index_1, style_1, ..., index_n, style_n]
     * where index_n is an index into the sourceCode, and style_n is a style
     * constant like PR_PLAIN.  index_n-1 <= index_n, and style_n-1 applies to
     * all characters in sourceCode[index_n-1:index_n].
     *
     * The stylePatterns is a list whose elements have the form
     * [style : string, pattern : RegExp, DEPRECATED, shortcut : string].
     *
     * Style is a style constant like PR_PLAIN, or can be a string of the
     * form 'lang-FOO', where FOO is a language extension describing the
     * language of the portion of the token in $1 after pattern executes.
     * E.g., if style is 'lang-lisp', and group 1 contains the text
     * '(hello (world))', then that portion of the token will be passed to the
     * registered lisp handler for formatting.
     * The text before and after group 1 will be restyled using this decorator
     * so decorators should take care that this doesn't result in infinite
     * recursion.  For example, the HTML lexer rule for SCRIPT elements looks
     * something like ['lang-js', /<[s]cript>(.+?)<\/script>/].  This may match
     * '<script>foo()<\/script>', which would cause the current decorator to
     * be called with '<script>' which would not match the same rule since
     * group 1 must not be empty, so it would be instead styled as PR_TAG by
     * the generic tag rule.  The handler registered for the 'js' extension would
     * then be called with 'foo()', and finally, the current decorator would
     * be called with '<\/script>' which would not match the original rule and
     * so the generic tag rule would identify it as a tag.
     *
     * Pattern must only match prefixes, and if it matches a prefix, then that
     * match is considered a token with the same style.
     *
     * Context is applied to the last non-whitespace, non-comment token
     * recognized.
     *
     * Shortcut is an optional string of characters, any of which, if the first
     * character, gurantee that this pattern and only this pattern matches.
     *
     * @param shortcutStylePatterns patterns that always start with
     *   a known character.  Must have a shortcut string.
     * @param fallthroughStylePatterns patterns that will be tried in
     *   order if the shortcut ones fail.  May have shortcuts.
     */
    protected CreateSimpleLexer(List<List<Object>> shortcutStylePatterns, List<List<Object>> fallthroughStylePatterns) throws Exception {
      this.fallthroughStylePatterns = fallthroughStylePatterns;

      List<List<Object>> allPatterns = new ArrayList<List<Object>>(shortcutStylePatterns);
      allPatterns.addAll(fallthroughStylePatterns);
      List<Pattern> allRegexs = new ArrayList<Pattern>();
      Map<String, Object> regexKeys = new HashMap<String, Object>();
      for (int i = 0, n = allPatterns.size(); i < n; ++i) {
        List<Object> patternParts = allPatterns.get(i);
        String shortcutChars = patternParts.size() > 3 ? (String) patternParts.get(3) : null;
        if (shortcutChars != null) {
          for (int c = shortcutChars.length(); --c >= 0;) {
            shortcuts.put(shortcutChars.charAt(c), patternParts);
          }
        }
        Pattern regex = (Pattern) patternParts.get(1);
        String k = regex.pattern();
        if (regexKeys.get(k) == null) {
          allRegexs.add(regex);
          regexKeys.put(k, new Object());
        }
      }
      allRegexs.add(Pattern.compile("[\0-\\uffff]"));
      tokenizer = new CombinePrefixPattern().combinePrefixPattern(allRegexs);

      nPatterns = fallthroughStylePatterns.size();
    }

    /**
     * Lexes job.sourceCode and produces an output array job.decorations of
     * style classes preceded by the position at which they start in
     * job.sourceCode in order.
     *
     * @param job an object like <pre>{
     *    sourceCode: {string} sourceText plain text,
     *    basePos: {int} position of job.sourceCode in the larger chunk of
     *        sourceCode.
     * }</pre>
     */
    public void decorate(Job job) {
      String sourceCode = job.getSourceCode();
      int basePos = job.getBasePos();
      /** Even entries are positions in source in ascending order.  Odd enties
       * are style markers (e.g., PR_COMMENT) that run from that position until
       * the end.
       * @type {Array.<number|string>}
       */
      List<Object> decorations = new ArrayList<Object>(Arrays.asList(new Object[]{basePos, PR_PLAIN}));
      int pos = 0;  // index into sourceCode
      String[] tokens = Util.match(tokenizer, sourceCode, true);
      Map<String, String> styleCache = new HashMap<String, String>();

      for (int ti = 0, nTokens = tokens.length; ti < nTokens; ++ti) {
        String token = tokens[ti];
        String style = styleCache.get(token);
        String[] match = null;

        boolean isEmbedded;
        if (style != null) {
          isEmbedded = false;
        } else {
          List<Object> patternParts = shortcuts.get(token.charAt(0));
          if (patternParts != null) {
            match = Util.match((Pattern) patternParts.get(1), token, false);
            style = (String) patternParts.get(0);
          } else {
            for (int i = 0; i < nPatterns; ++i) {
              patternParts = fallthroughStylePatterns.get(i);
              match = Util.match((Pattern) patternParts.get(1), token, false);
              if (match.length != 0) {
                style = (String) patternParts.get(0);
                break;
              }
            }

            if (match.length == 0) {  // make sure that we make progress
              style = PR_PLAIN;
            }
          }

          isEmbedded = style != null && style.length() >= 5 && style.startsWith("lang-");
          if (isEmbedded && !(match.length > 1 && match[1] != null)) {
            isEmbedded = false;
            style = PR_SOURCE;
          }

          if (!isEmbedded) {
            styleCache.put(token, style);
          }
        }

        int tokenStart = pos;
        pos += token.length();

        if (!isEmbedded) {
          decorations.add(basePos + tokenStart);
          decorations.add(style);
        } else {  // Treat group 1 as an embedded block of source code.
          String embeddedSource = match[1];
          int embeddedSourceStart = token.indexOf(embeddedSource);
          int embeddedSourceEnd = embeddedSourceStart + embeddedSource.length();
          if (match.length > 2 && match[2] != null) {
            // If embeddedSource can be blank, then it would match at the
            // beginning which would cause us to infinitely recurse on the
            // entire token, so we catch the right context in match[2].
            embeddedSourceEnd = token.length() - match[2].length();
            embeddedSourceStart = embeddedSourceEnd - embeddedSource.length();
          }
          String lang = style.substring(5);
          // Decorate the left of the embedded source
          appendDecorations(basePos + tokenStart,
                  token.substring(0, embeddedSourceStart),
                  this, decorations);
          // Decorate the embedded source
          appendDecorations(basePos + tokenStart + embeddedSourceStart,
                  embeddedSource,
                  langHandlerForExtension(lang, embeddedSource),
                  decorations);
          // Decorate the right of the embedded section
          appendDecorations(basePos + tokenStart + embeddedSourceEnd,
                  token.substring(embeddedSourceEnd),
                  this, decorations);
        }
      }

      job.setDecorations(Util.removeDuplicates(decorations, job.getSourceCode()));
    }
  }

  /** returns a function that produces a list of decorations from source text.
   *
   * This code treats ", ', and ` as string delimiters, and \ as a string
   * escape.  It does not recognize perl's qq() style strings.
   * It has no special handling for double delimiter escapes as in basic, or
   * the tripled delimiters used in python, but should work on those regardless
   * although in those cases a single string literal may be broken up into
   * multiple adjacent string literals.
   *
   * It recognizes C, C++, and shell style comments.
   *
   * @param options a set of optional parameters.
   * @return a function that examines the source code
   *     in the input job and builds the decoration list.
   */
  protected CreateSimpleLexer sourceDecorator(Map<String, Object> options) throws Exception {
    List<List<Object>> shortcutStylePatterns = new ArrayList<List<Object>>();
    List<List<Object>> fallthroughStylePatterns = new ArrayList<List<Object>>();
    if (options.get("tripleQuotedStrings") != null) {
      // '''multi-line-string''', 'single-line-string', and double-quoted
      shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
                Pattern.compile("^(?:\\'\\'\\'(?:[^\\'\\\\]|\\\\[\\s\\S]|\\'{1,2}(?=[^\\']))*(?:\\'\\'\\'|$)|\\\"\\\"\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S]|\\\"{1,2}(?=[^\\\"]))*(?:\\\"\\\"\\\"|$)|\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$))"),
                null,
                "'\""}));
    } else if (options.get("multiLineStrings") != null) {
      // 'multi-line-string', "multi-line-string"
      shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
                Pattern.compile("^(?:\\'(?:[^\\\\\\']|\\\\[\\s\\S])*(?:\\'|$)|\\\"(?:[^\\\\\\\"]|\\\\[\\s\\S])*(?:\\\"|$)|\\`(?:[^\\\\\\`]|\\\\[\\s\\S])*(?:\\`|$))"),
                null,
                "'\"`"}));
    } else {
      // 'single-line-string', "single-line-string"
      shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
                Pattern.compile("^(?:\\'(?:[^\\\\\\'\r\n]|\\\\.)*(?:\\'|$)|\\\"(?:[^\\\\\\\"\r\n]|\\\\.)*(?:\\\"|$))"),
                null,
                "\"'"}));
    }
    if (options.get("verbatimStrings") != null) {
      // verbatim-string-literal production from the C# grammar.  See issue 93.
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
                Pattern.compile("^@\\\"(?:[^\\\"]|\\\"\\\")*(?:\\\"|$)"),
                null}));
    }
    Object hc = options.get("hashComments");
    if (hc != null) {
      if (options.get("cStyleComments") != null) {
        if ((hc instanceof Integer) && (Integer) hc > 1) {  // multiline hash comments
          shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
                    Pattern.compile("^#(?:##(?:[^#]|#(?!##))*(?:###|$)|.*)"),
                    null,
                    "#"}));
        } else {
          // Stop C preprocessor declarations at an unclosed open comment
          shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
                    Pattern.compile("^#(?:(?:define|e(?:l|nd)if|else|error|ifn?def|include|line|pragma|undef|warning)\\b|[^\r\n]*)"),
                    null,
                    "#"}));
        }
        // #include <stdio.h>
        fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_STRING,
                  Pattern.compile("^<(?:(?:(?:\\.\\.\\/)*|\\/?)(?:[\\w-]+(?:\\/[\\w-]+)+)?[\\w-]+\\.h(?:h|pp|\\+\\+)?|[a-z]\\w*)>"),
                  null}));
      } else {
        shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
                  Pattern.compile("^#[^\r\n]*"),
                  null,
                  "#"}));
      }
    }
    if (options.get("cStyleComments") != null) {
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
                Pattern.compile("^\\/\\/[^\r\n]*"),
                null}));

      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_COMMENT,
                Pattern.compile("^\\/\\*[\\s\\S]*?(?:\\*\\/|$)"),
                null}));
    }
    if (options.get("regexLiterals") != null) {
      /**
       * @const
       */
      String REGEX_LITERAL =
              // A regular expression literal starts with a slash that is
              // not followed by * or / so that it is not confused with
              // comments.
              "/(?=[^/*])"
              // and then contains any number of raw characters,
              + "(?:[^/\\x5B\\x5C]"
              // escape sequences (\x5C),
              + "|\\x5C[\\s\\S]"
              // or non-nesting character sets (\x5B\x5D);
              + "|\\x5B(?:[^\\x5C\\x5D]|\\x5C[\\s\\S])*(?:\\x5D|$))+"
              // finally closed by a /.
              + "/";
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{"lang-regex",
                Pattern.compile("^" + REGEXP_PRECEDER_PATTERN + "(" + REGEX_LITERAL + ")")}));
    }

    Pattern types = (Pattern) options.get("types");
    if (types != null) {
      fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_TYPE, types}));
    }

    if (options.get("keywords") != null) {
      String keywords = ((String) options.get("keywords")).replaceAll("^ | $", "");
      if (keywords.length() != 0) {
        fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_KEYWORD,
                  Pattern.compile("^(?:" + keywords.replaceAll("[\\s,]+", "|") + ")\\b"),
                  null}));
      }
    }

    shortcutStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
              Pattern.compile("^\\s+"),
              null,
              " \r\n\t" + Character.toString((char) 0xA0)
            }));

    // TODO(mikesamuel): recognize non-latin letters and numerals in idents
    fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_LITERAL,
              Pattern.compile("^@[a-z_$][a-z_$@0-9]*", Pattern.CASE_INSENSITIVE),
              null}));
    fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_TYPE,
              Pattern.compile("^(?:[@_]?[A-Z]+[a-z][A-Za-z_$@0-9]*|\\w+_t\\b)"),
              null}));
    fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
              Pattern.compile("^[a-z_$][a-z_$@0-9]*", Pattern.CASE_INSENSITIVE),
              null}));
    fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_LITERAL,
              Pattern.compile("^(?:"
              // A hex number
              + "0x[a-f0-9]+"
              // or an octal or decimal number,
              + "|(?:\\d(?:_\\d+)*\\d*(?:\\.\\d*)?|\\.\\d\\+)"
              // possibly in scientific notation
              + "(?:e[+\\-]?\\d+)?"
              + ')'
              // with an optional modifier like UL for unsigned long
              + "[a-z]*", Pattern.CASE_INSENSITIVE),
              null,
              "0123456789"}));
    // Don't treat escaped quotes in bash as starting strings.  See issue 144.
    fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PLAIN,
              Pattern.compile("^\\\\[\\s\\S]?"),
              null}));

    // The Bash man page says

    // A word is a sequence of characters considered as a single
    // unit by GRUB. Words are separated by metacharacters,
    // which are the following plus space, tab, and newline: { }
    // | & $ ; < >
    // ...

    // A word beginning with # causes that word and all remaining
    // characters on that line to be ignored.

    // which means that only a '#' after /(?:^|[{}|&$;<>\s])/ starts a
    // comment but empirically
    // $ echo {#}
    // {#}
    // $ echo \$#
    // $#
    // $ echo }#
    // }#

    // so /(?:^|[|&;<>\s])/ is more appropriate.

    // http://gcc.gnu.org/onlinedocs/gcc-2.95.3/cpp_1.html#SEC3
    // suggests that this definition is compatible with a
    // default mode that tries to use a single token definition
    // to recognize both bash/python style comments and C
    // preprocessor directives.

    // This definition of punctuation does not include # in the list of
    // follow-on exclusions, so # will not be broken before if preceeded
    // by a punctuation character.  We could try to exclude # after
    // [|&;<>] but that doesn't seem to cause many major problems.
    // If that does turn out to be a problem, we should change the below
    // when hc is truthy to include # in the run of punctuation characters
    // only when not followint [|&;<>].
    final String punctation = "^.[^\\s\\w\\.$@\\'\\\"\\`\\/\\\\]*";
    fallthroughStylePatterns.add(Arrays.asList(new Object[]{PR_PUNCTUATION,
              Pattern.compile(punctation),
              null}));

    return new CreateSimpleLexer(shortcutStylePatterns, fallthroughStylePatterns);
  }
  /** Maps language-specific file extensions to handlers. */
  protected Map<String, Object> langHandlerRegistry = new HashMap<String, Object>();

  /** Register a language handler for the given file extensions.
   * @param handler a function from source code to a list
   *      of decorations.  Takes a single argument job which describes the
   *      state of the computation.   The single parameter has the form
   *      {@code {
   *        sourceCode: {string} as plain text.
   *        decorations: {Array.<number|string>} an array of style classes
   *                     preceded by the position at which they start in
   *                     job.sourceCode in order.
   *                     The language handler should assigned this field.
   *        basePos: {int} the position of source in the larger source chunk.
   *                 All positions in the output decorations array are relative
   *                 to the larger source chunk.
   *      } }
   * @param fileExtensions
   */
  protected void registerLangHandler(CreateSimpleLexer handler, List<String> fileExtensions) throws Exception {
    for (int i = fileExtensions.size(); --i >= 0;) {
      String ext = fileExtensions.get(i);
      if (langHandlerRegistry.get(ext) == null) {
        langHandlerRegistry.put(ext, handler);
      } else {
        throw new Exception("cannot override language handler " + ext);
      }
    }
  }

  /**
   * Register language handler. The clazz will not be instantiated
   * @param clazz the class of the language
   * @throws Exception cannot instantiate the object using the class,
   * or language handler with specified extension exist already
   */
  public void register(Class<? extends Lang> clazz) throws Exception {
    if (clazz == null) {
      throw new NullPointerException("argument 'clazz' cannot be null");
    }
    List<String> fileExtensions = getFileExtensionsFromClass(clazz);
    for (int i = fileExtensions.size(); --i >= 0;) {
      String ext = fileExtensions.get(i);
      if (langHandlerRegistry.get(ext) == null) {
        langHandlerRegistry.put(ext, clazz);
      } else {
        throw new Exception("cannot override language handler " + ext);
      }
    }
  }

  protected List<String> getFileExtensionsFromClass(Class<? extends Lang> clazz) throws Exception {
    Method getExtensionsMethod = clazz.getMethod("getFileExtensions", (Class<?>[]) null);
    return (List<String>) getExtensionsMethod.invoke(null, null);
  }

  /**
   * Get the parser for the extension specified. 
   * @param extension the file extension, if null, default parser will be returned
   * @param source the source code
   * @return the parser
   */
  public CreateSimpleLexer langHandlerForExtension(String extension, String source) {
    if (!(extension != null && langHandlerRegistry.get(extension) != null)) {
      // Treat it as markup if the first non whitespace character is a < and
      // the last non-whitespace character is a >.
      extension = Util.test(Pattern.compile("^\\s*<"), source)
              ? "default-markup"
              : "default-code";
    }

    Object handler = langHandlerRegistry.get(extension);
    if (handler instanceof CreateSimpleLexer) {
      return (CreateSimpleLexer) handler;
    } else {
      CreateSimpleLexer _simpleLexer;
      try {
        Lang _lang = ((Class<Lang>) handler).newInstance();
        _simpleLexer = new CreateSimpleLexer(_lang.getShortcutStylePatterns(), _lang.getFallthroughStylePatterns());

        List<Lang> extendedLangs = _lang.getExtendedLangs();
        for (Lang _extendedLang : extendedLangs) {
          register(_extendedLang.getClass());
        }

        List<String> fileExtensions = getFileExtensionsFromClass((Class<Lang>) handler);
        for (String _extension : fileExtensions) {
          langHandlerRegistry.put(_extension, _simpleLexer);
        }
      } catch (Exception ex) {
        LOG.log(Level.SEVERE, null, ex);
        return null;
      }

      return _simpleLexer;
    }
  }
}
