// Copyright (C) 2010 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.lang;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Pattern;
import prettify.Lang;
import prettify.Prettify;

/**
 * Registers a language handler for the Go language..
 * <p>
 * Based on the lexical grammar at 
 * http://golang.org/doc/go_spec.html#Lexical_elements
 * <p>
 * Go uses a minimal style for highlighting so the below does not distinguish
 * strings, keywords, literals, etc. by design.
 * From a discussion with the Go designers:
 * <pre>
 * On Thursday, July 22, 2010, Mike Samuel <...> wrote:
 * > On Thu, Jul 22, 2010, Rob 'Commander' Pike <...> wrote:
 * >> Personally, I would vote for the subdued style godoc presents at http://golang.org
 * >>
 * >> Not as fancy as some like, but a case can be made it's the official style.
 * >> If people want more colors, I wouldn't fight too hard, in the interest of
 * >> encouragement through familiarity, but even then I would ask to shy away
 * >> from technicolor starbursts.
 * >
 * > Like http://golang.org/pkg/go/scanner/ where comments are blue and all
 * > other content is black?  I can do that.
 * </pre>
 *
 * @author mikesamuel@gmail.com
 */
public class LangGo extends Lang {

    public LangGo() {
        List<List<Object>> _shortcutStylePatterns = new ArrayList<List<Object>>();
        List<List<Object>> _fallthroughStylePatterns = new ArrayList<List<Object>>();

        // Whitespace is made up of spaces, tabs and newline characters.
        _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^[\\t\\n\\r \\xA0]+"), null, "\t\n\r " + Character.toString((char) 0xA0)}));
        // Not escaped as a string.  See note on minimalism above.
        _shortcutStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^(?:\\\"(?:[^\\\"\\\\]|\\\\[\\s\\S])*(?:\\\"|$)|\\'(?:[^\\'\\\\]|\\\\[\\s\\S])+(?:\\'|$)|`[^`]*(?:`|$))"), null, "\"'"}));
        // Block comments are delimited by /* and */.
        // Single-line comments begin with // and extend to the end of a line.
        _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_COMMENT, Pattern.compile("^(?:\\/\\/[^\\r\\n]*|\\/\\*[\\s\\S]*?\\*\\/)")}));
        _fallthroughStylePatterns.add(Arrays.asList(new Object[]{Prettify.PR_PLAIN, Pattern.compile("^(?:[^\\/\\\"\\'`]|\\/(?![\\/\\*]))+", Pattern.CASE_INSENSITIVE)}));

        setShortcutStylePatterns(_shortcutStylePatterns);
        setFallthroughStylePatterns(_fallthroughStylePatterns);
    }

    public static List<String> getFileExtensions() {
        return Arrays.asList(new String[]{"go"});
    }
}
