/*
 * Copyright 2008 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 com.google.gwt.dev.cfg;

import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.Linker;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.linker.LinkerOrder;
import com.google.gwt.dev.js.JsParser;
import com.google.gwt.dev.js.JsParserException;
import com.google.gwt.dev.js.JsParserException.SourceDetail;
import com.google.gwt.dev.js.ast.JsExprStmt;
import com.google.gwt.dev.js.ast.JsFunction;
import com.google.gwt.dev.js.ast.JsProgram;
import com.google.gwt.dev.js.ast.JsStatement;
import com.google.gwt.dev.util.Empty;
import com.google.gwt.dev.util.Util;
import com.google.gwt.dev.util.xml.AttributeConverter;
import com.google.gwt.dev.util.xml.Schema;

import java.io.IOException;
import java.io.StringReader;
import java.net.URL;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

// CHECKSTYLE_NAMING_OFF
/**
 * Configures a module definition object using XML.
 */
public class ModuleDefSchema extends Schema {

  private final class BodySchema extends Schema {

    protected final String __add_linker_1_name = null;

    protected final String __clear_configuration_property_1_name = null;

    protected final String __define_configuration_property_1_name = null;

    protected final String __define_configuration_property_2_is_multi_valued = null;

    protected final String __define_linker_1_name = null;

    protected final String __define_linker_2_class = null;

    protected final String __define_property_1_name = null;

    protected final String __define_property_2_values = null;

    protected final String __entry_point_1_class = null;

    protected final String __extend_configuration_property_1_name = null;

    protected final String __extend_configuration_property_2_value = null;

    protected final String __extend_property_1_name = null;

    protected final String __extend_property_2_values = null;

    protected final String __generate_with_1_class = null;

    protected final String __inherits_1_name = null;

    protected final String __property_provider_1_name = null;

    protected final String __public_1_path = null;

    protected final String __public_2_includes = "";

    protected final String __public_3_excludes = "";

    protected final String __public_4_defaultexcludes = "yes";

    protected final String __public_5_casesensitive = "true";

    protected final String __replace_with_1_class = null;

    protected final String __script_1_src = null;

    protected final String __servlet_1_path = null;

    protected final String __servlet_2_class = null;

    protected final String __set_configuration_property_1_name = null;

    protected final String __set_configuration_property_2_value = null;

    protected final String __set_property_1_name = null;

    protected final String __set_property_2_value = null;

    protected final String __set_property_fallback_1_name = null;

    protected final String __set_property_fallback_2_value = null;

    protected final String __source_1_path = "";

    protected final String __source_2_includes = "";

    protected final String __source_3_excludes = "";

    protected final String __source_4_defaultexcludes = "yes";

    protected final String __source_5_casesensitive = "true";

    protected final String __stylesheet_1_src = null;

    protected final String __super_source_1_path = "";

    protected final String __super_source_2_includes = "";

    protected final String __super_source_3_excludes = "";

    protected final String __super_source_4_defaultexcludes = "yes";

    protected final String __super_source_5_casesensitive = "true";

    /**
     * Used to accumulate binding property conditions before recording the
     * newly-allowed values.
     */
    private ConditionAll bindingPropertyCondition;

    private Schema fChild;

    protected Schema __add_linker_begin(LinkerName name)
        throws UnableToCompleteException {
      if (moduleDef.getLinker(name.name) == null) {
        Messages.LINKER_NAME_INVALID.log(logger, name.name, null);
        throw new UnableToCompleteException();
      }
      moduleDef.addLinker(name.name);
      return null;
    }

    protected Schema __clear_configuration_property_begin(PropertyName name)
        throws UnableToCompleteException {
      // Don't allow configuration properties with the same name as a
      // deferred-binding property.
      Property prop = moduleDef.getProperties().find(name.token);
      if (prop == null) {
        logger.log(TreeLogger.ERROR, "No property named " + name.token
            + " has been defined");
        throw new UnableToCompleteException();
      } else if (!(prop instanceof ConfigurationProperty)) {
        if (prop instanceof BindingProperty) {
          logger.log(TreeLogger.ERROR, "The property " + name.token
              + " is already defined as a deferred-binding property");
        } else {
          logger.log(TreeLogger.ERROR, "The property " + name.token
              + " is already defined as a property of unknown type");
        }
        throw new UnableToCompleteException();
      }

      ((ConfigurationProperty) prop).clear();

      // No children.
      return null;
    }

    protected Schema __define_configuration_property_begin(PropertyName name,
        String is_multi_valued) throws UnableToCompleteException {
      boolean isMultiValued = toPrimitiveBoolean(is_multi_valued);

      // Don't allow configuration properties with the same name as a
      // deferred-binding property.
      Property existingProperty = moduleDef.getProperties().find(name.token);
      if (existingProperty == null) {
        // Create the property
        moduleDef.getProperties().createConfiguration(name.token, isMultiValued);
        if (!propertyDefinitions.containsKey(name.token)) {
          propertyDefinitions.put(name.token, moduleName);
        }
      } else if (existingProperty instanceof ConfigurationProperty) {
        // Allow redefinition only if the 'is-multi-valued' setting is identical
        // The previous definition may have been explicit, via
        // <define-configuration-property>, or implicit, via
        // <set-configuration-property>. In the latter case, the
        // value of the 'is-multi-valued' attribute was taken as false.
        String originalDefinition = propertyDefinitions.get(name.token);
        if (((ConfigurationProperty) existingProperty).allowsMultipleValues() != isMultiValued) {
          if (originalDefinition != null) {
            logger.log(
                TreeLogger.ERROR,
                "The configuration property named "
                    + name.token
                    + " is already defined with a different 'is-multi-valued' setting");
          } else {
            logger.log(
                TreeLogger.ERROR,
                "The configuration property named "
                    + name.token
                    + " is already defined implicitly by 'set-configuration-property'"
                    + " in " + propertySettings.get(name.token)
                    + " with 'is-multi-valued' set to 'false'");
          }
          throw new UnableToCompleteException();
        } else {
          if (originalDefinition != null) {
            logger.log(TreeLogger.WARN,
                "Ignoring identical definition of the configuration property named "
                    + name.token + " (originally defined in "
                    + originalDefinition + ", redefined in " + moduleName + ")");
          } else {
            logger.log(TreeLogger.WARN,
                "Definition of already set configuration property named "
                    + name.token + " in " + moduleName + " (set in "
                    + propertySettings.get(name.token)
                    + ").  This may be disallowed in the future.");
          }
        }
      } else {
        if (existingProperty instanceof BindingProperty) {
          logger.log(TreeLogger.ERROR, "The property " + name.token
              + " is already defined as a deferred-binding property");
        } else {
          // Future proofing if other subclasses are added.
          logger.log(TreeLogger.ERROR, "May not replace property named "
              + name.token + " of unknown type "
              + existingProperty.getClass().getName());
        }
        throw new UnableToCompleteException();
      }

      // No children.
      return null;
    }

    protected Schema __define_linker_begin(LinkerName name,
        Class<? extends Linker> linker) throws UnableToCompleteException {
      if (!Linker.class.isAssignableFrom(linker)) {
        logger.log(TreeLogger.ERROR, "A linker must extend "
            + Linker.class.getName(), null);
        throw new UnableToCompleteException();
      }
      if (linker.getAnnotation(LinkerOrder.class) == null) {
        logger.log(TreeLogger.ERROR, "Linkers must be annotated with the "
            + LinkerOrder.class.getName() + " annotation", null);
        throw new UnableToCompleteException();
      }
      moduleDef.defineLinker(logger, name.name, linker);
      return null;
    }

    protected Schema __define_property_begin(PropertyName name,
        PropertyValue[] values) throws UnableToCompleteException {

      Property existingProperty = moduleDef.getProperties().find(name.token);
      if (existingProperty != null) {
        // Disallow redefinition of properties, but provide a type-sensitive
        // error message to aid in diagnosis.
        if (existingProperty instanceof BindingProperty) {
          logger.log(TreeLogger.ERROR, "The deferred-binding property named "
              + name.token + " may not be redefined.");
        } else if (existingProperty instanceof ConfigurationProperty) {
          logger.log(TreeLogger.ERROR, "The property " + name.token
              + " is already defined as a configuration property");
        } else {
          // Future proofing if other subclasses are added.
          logger.log(TreeLogger.ERROR, "May not replace property named "
              + name.token + " of unknown type "
              + existingProperty.getClass().getName());
        }
        throw new UnableToCompleteException();
      }

      BindingProperty prop = moduleDef.getProperties().createBinding(name.token);

      for (int i = 0; i < values.length; i++) {
        prop.addDefinedValue(prop.getRootCondition(), values[i].token);
      }

      // No children.
      return null;
    }

    protected Schema __entry_point_begin(String className) {
      moduleDef.addEntryPointTypeName(className);
      return null;
    }

    protected Schema __extend_configuration_property_begin(PropertyName name,
        String value) throws UnableToCompleteException {

      // Property must already exist as a configuration property
      Property prop = moduleDef.getProperties().find(name.token);
      if ((prop == null) || !(prop instanceof ConfigurationProperty)) {
        logger.log(TreeLogger.ERROR, "The property " + name.token
            + " must already exist as a configuration property");
        throw new UnableToCompleteException();
      }

      ConfigurationProperty configProp = (ConfigurationProperty) prop;
      if (!configProp.allowsMultipleValues()) {
        logger.log(TreeLogger.ERROR, "The property " + name.token
            + " does not support multiple values");
        throw new UnableToCompleteException();
      }
      configProp.addValue(value);

      return null;
    }

    protected Schema __extend_property_begin(BindingProperty property,
        PropertyValue[] values) {
      for (int i = 0; i < values.length; i++) {
        property.addDefinedValue(property.getRootCondition(), values[i].token);
      }

      // No children.
      return null;
    }

    protected Schema __fail_begin() {
      RuleFail rule = new RuleFail();
      moduleDef.getRules().prepend(rule);
      return new FullConditionSchema(rule.getRootCondition());
    }

    protected Schema __generate_with_begin(Class<? extends Generator> generator)
        throws UnableToCompleteException {
      if (!Generator.class.isAssignableFrom(generator)) {
        logger.log(TreeLogger.ERROR, "A generator must extend "
            + Generator.class.getName(), null);
        throw new UnableToCompleteException();
      }
      RuleGenerateWith rule = new RuleGenerateWith(generator);
      moduleDef.getRules().prepend(rule);
      return new FullConditionSchema(rule.getRootCondition());
    }

    protected Schema __inherits_begin(String name)
        throws UnableToCompleteException {
      TreeLogger branch = logger.branch(TreeLogger.TRACE,
          "Loading inherited module '" + name + "'", null);
      loader.nestedLoad(branch, name, moduleDef);
      return null;
    }

    @SuppressWarnings("unused")
    protected Schema __property_provider_begin(BindingProperty property) {
      return fChild = new ScriptSchema();
    }

    protected void __property_provider_end(BindingProperty property)
        throws UnableToCompleteException {
      ScriptSchema childSchema = ((ScriptSchema) fChild);
      String script = childSchema.getScript();
      if (script == null) {
        // This is a problem.
        //
        logger.log(TreeLogger.ERROR,
            "Property providers must specify a JavaScript body", null);
        throw new UnableToCompleteException();
      }

      int lineNumber = childSchema.getStartLineNumber();
      JsFunction fn = parseJsBlock(lineNumber, script);

      property.setProvider(new PropertyProvider(fn.getBody().toSource()));
    }

    @SuppressWarnings("unused")
    protected Schema __public_begin(String path, String includes,
        String excludes, String defaultExcludes, String caseSensitive) {
      return fChild = new IncludeExcludeSchema();
    }

    protected void __public_end(String path, String includes, String excludes,
        String defaultExcludes, String caseSensitive) {
      IncludeExcludeSchema childSchema = ((IncludeExcludeSchema) fChild);
      foundAnyPublic = true;

      Set<String> includeSet = childSchema.getIncludes();
      addDelimitedStringToSet(includes, "[ ,]", includeSet);
      String[] includeList = includeSet.toArray(new String[includeSet.size()]);

      Set<String> excludeSet = childSchema.getExcludes();
      addDelimitedStringToSet(excludes, "[ ,]", excludeSet);
      String[] excludeList = excludeSet.toArray(new String[excludeSet.size()]);

      boolean doDefaultExcludes = toPrimitiveBoolean(defaultExcludes);
      boolean doCaseSensitive = toPrimitiveBoolean(caseSensitive);

      addPublicPackage(modulePackageAsPath, path, includeList, excludeList,
          doDefaultExcludes, doCaseSensitive);
    }

    protected Schema __replace_with_begin(String className) {
      RuleReplaceWith rule = new RuleReplaceWith(className);
      moduleDef.getRules().prepend(rule);
      return new FullConditionSchema(rule.getRootCondition());
    }

    /**
     * @param src a partial or full url to a script file to inject
     * @return <code>null</code> since there can be no children
     */
    @SuppressWarnings("unused")
    protected Schema __script_begin(String src) {
      return fChild = new ScriptSchema();
    }

    protected void __script_end(String src) {
      ScriptSchema childSchema = (ScriptSchema) fChild;
      String js = childSchema.getScript();
      if (js != null) {
        logger.log(
            TreeLogger.WARN,
            "Injected scripts no longer require an associated JavaScript block.",
            null);
      }
      moduleDef.getScripts().append(new Script(src));
    }

    protected Schema __servlet_begin(String path, String servletClass)
        throws UnableToCompleteException {

      // Only absolute paths, although it is okay to have multiple slashes.
      if (!path.startsWith("/")) {
        logger.log(TreeLogger.ERROR, "Servlet path '" + path
            + "' must begin with forward slash (e.g. '/foo')", null);
        throw new UnableToCompleteException();
      }

      // Map the path within this module.
      moduleDef.mapServlet(path, servletClass);

      return null;
    }

    protected Schema __set_configuration_property_begin(PropertyName name,
        String value) throws UnableToCompleteException {

      Property existingProperty = moduleDef.getProperties().find(name.token);
      if (existingProperty == null) {
        // If a property is created by "set-configuration-property" without
        // a previous "define-configuration-property", allow it for backwards
        // compatibility but don't allow multiple values.
        existingProperty = moduleDef.getProperties().createConfiguration(
            name.token, false);
        if (!propertySettings.containsKey(name.token)) {
          propertySettings.put(name.token, moduleName);
        }

        logger.log(TreeLogger.WARN, "Setting configuration property named "
            + name.token + " in " + moduleName
            + " that has not been previously defined."
            + "  This may be disallowed in the future.");
      } else if (!(existingProperty instanceof ConfigurationProperty)) {
        if (existingProperty instanceof BindingProperty) {
          logger.log(TreeLogger.ERROR, "The property " + name.token
              + " is already defined as a deferred-binding property");
        } else {
          // Future proofing if other subclasses are added.
          logger.log(TreeLogger.ERROR, "May not replace property named "
              + name.token + " of unknown type "
              + existingProperty.getClass().getName());
        }
        throw new UnableToCompleteException();
      }
      ((ConfigurationProperty) existingProperty).setValue(value);

      // No children.
      return null;
    }

    @SuppressWarnings("unused")
    protected Schema __set_property_begin(BindingProperty prop,
        PropertyValue[] value) throws UnableToCompleteException {
      bindingPropertyCondition = new ConditionAll();
      return new PropertyConditionSchema(bindingPropertyCondition);
    }

    protected void __set_property_end(BindingProperty prop,
        PropertyValue[] value) throws UnableToCompleteException {
      boolean error = false;
      String[] stringValues = new String[value.length];
      for (int i = 0, len = stringValues.length; i < len; i++) {
        if (!prop.isDefinedValue(stringValues[i] = value[i].token)) {
          logger.log(TreeLogger.ERROR, "The value " + stringValues[i]
              + " was not previously defined.");
          error = true;
        }
      }
      if (error) {
        throw new UnableToCompleteException();
      }

      // No conditions were specified, so use the property's root condition
      if (!bindingPropertyCondition.getConditions().iterator().hasNext()) {
        bindingPropertyCondition = prop.getRootCondition();
      }

      prop.setAllowedValues(bindingPropertyCondition, stringValues);
    }

    protected Schema __set_property_fallback_begin(BindingProperty prop,
        PropertyValue value) throws UnableToCompleteException {
      boolean error = true;
      for (String possibleValue : prop.getAllowedValues(prop.getRootCondition())) {
        if (possibleValue.equals(value.token)) {
          error = false;
          break;
        }
      }
      if (error) {
        logger.log(TreeLogger.ERROR, "The fallback value '" + value.token
            + "' was not previously defined for property '" + prop.getName()
            + "'");
        throw new UnableToCompleteException();
      }
      prop.setFallback(value.token);
      return null;
    }

    /**
     * Indicates which subdirectories contain translatable source without
     * necessarily adding a sourcepath entry.
     */
    @SuppressWarnings("unused")
    protected Schema __source_begin(String path, String includes,
        String excludes, String defaultExcludes, String caseSensitive) {
      return fChild = new IncludeExcludeSchema();
    }

    protected void __source_end(String path, String includes, String excludes,
        String defaultExcludes, String caseSensitive) {
      addSourcePackage(path, includes, excludes, defaultExcludes,
          caseSensitive, false);
    }

    /**
     * @param src a partial or full url to a stylesheet file to inject
     * @return <code>null</code> since there can be no children
     */
    protected Schema __stylesheet_begin(String src) {
      moduleDef.getStyles().append(src);
      return null;
    }

    /**
     * Like adding a translatable source package, but such that it uses the
     * module's package itself as its sourcepath root entry.
     */
    @SuppressWarnings("unused")
    protected Schema __super_source_begin(String path, String includes,
        String excludes, String defaultExcludes, String caseSensitive) {
      return fChild = new IncludeExcludeSchema();
    }

    protected void __super_source_end(String path, String includes,
        String excludes, String defaultExcludes, String caseSensitive) {
      addSourcePackage(path, includes, excludes, defaultExcludes,
          caseSensitive, true);
    }

    private void addDelimitedStringToSet(String delimited, String delimiter,
        Set<String> toSet) {
      if (delimited.length() > 0) {
        String[] split = delimited.split(delimiter);
        for (int i = 0; i < split.length; ++i) {
          if (split[i].length() > 0) {
            toSet.add(split[i]);
          }
        }
      }
    }

    private void addPublicPackage(String parentDir, String relDir,
        String[] includeList, String[] excludeList, boolean defaultExcludes,
        boolean caseSensitive) {
      String normChildDir = normalizePathEntry(relDir);
      if (normChildDir.startsWith("/")) {
        logger.log(TreeLogger.WARN, "Non-relative public package: "
            + normChildDir, null);
        return;
      }
      if (normChildDir.startsWith("./") || normChildDir.indexOf("/./") >= 0) {
        logger.log(TreeLogger.WARN, "Non-canonical public package: "
            + normChildDir, null);
        return;
      }
      if (normChildDir.startsWith("../") || normChildDir.indexOf("/../") >= 0) {
        logger.log(TreeLogger.WARN, "Non-canonical public package: "
            + normChildDir, null);
        return;
      }
      String fullDir = parentDir + normChildDir;
      moduleDef.addPublicPackage(fullDir, includeList, excludeList,
          defaultExcludes, caseSensitive);
    }

    private void addSourcePackage(String relDir, String includes,
        String excludes, String defaultExcludes, String caseSensitive,
        boolean isSuperSource) {
      IncludeExcludeSchema childSchema = ((IncludeExcludeSchema) fChild);
      foundExplicitSourceOrSuperSource = true;

      Set<String> includeSet = childSchema.getIncludes();
      addDelimitedStringToSet(includes, "[ ,]", includeSet);
      String[] includeList = includeSet.toArray(new String[includeSet.size()]);

      Set<String> excludeSet = childSchema.getExcludes();
      addDelimitedStringToSet(excludes, "[ ,]", excludeSet);
      String[] excludeList = excludeSet.toArray(new String[excludeSet.size()]);

      boolean doDefaultExcludes = toPrimitiveBoolean(defaultExcludes);
      boolean doCaseSensitive = toPrimitiveBoolean(caseSensitive);

      addSourcePackage(modulePackageAsPath, relDir, includeList, excludeList,
          doDefaultExcludes, doCaseSensitive, isSuperSource);
    }

    private void addSourcePackage(String modulePackagePath, String relDir,
        String[] includeList, String[] excludeList, boolean defaultExcludes,
        boolean caseSensitive, boolean isSuperSource) {
      String normChildDir = normalizePathEntry(relDir);
      if (normChildDir.startsWith("/")) {
        logger.log(TreeLogger.WARN, "Non-relative source package: "
            + normChildDir, null);
        return;
      }
      if (normChildDir.startsWith("./") || normChildDir.indexOf("/./") >= 0) {
        logger.log(TreeLogger.WARN, "Non-canonical source package: "
            + normChildDir, null);
        return;
      }
      if (normChildDir.startsWith("../") || normChildDir.indexOf("/../") >= 0) {
        logger.log(TreeLogger.WARN, "Non-canonical source package: "
            + normChildDir, null);
        return;
      }

      String fullPackagePath = modulePackagePath + normChildDir;

      if (isSuperSource) {
        /*
         * Super source does not include the module package path as part of the
         * logical class names.
         */
        moduleDef.addSuperSourcePackage(fullPackagePath, includeList,
            excludeList, defaultExcludes, caseSensitive);
      } else {
        /*
         * Add the full package path to the include and exclude lists since the
         * logical name of classes on the source path includes the package path
         * but the include and exclude lists do not.
         */
        addPrefix(includeList, fullPackagePath);
        addPrefix(excludeList, fullPackagePath);

        moduleDef.addSourcePackage(fullPackagePath, includeList, excludeList,
            defaultExcludes, caseSensitive);
      }
    }

    /**
     * Normalizes a path entry such that it does not start with but does end
     * with '/'.
     */
    private String normalizePathEntry(String path) {
      path = path.trim();

      if (path.length() == 0) {
        return "";
      }

      path = path.replace('\\', '/');

      if (!path.endsWith("/")) {
        path += "/";
      }

      return path;
    }
  }

  /**
   * Processes attributes of java.lang.Class type.
   */
  private final class ClassAttrCvt extends AttributeConverter {
    @Override
    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {
      try {
        ClassLoader cl = Thread.currentThread().getContextClassLoader();
        return cl.loadClass(value);
      } catch (ClassNotFoundException e) {
        Messages.UNABLE_TO_LOAD_CLASS.log(logger, value, e);
        throw new UnableToCompleteException();
      }
    }
  }

  /**
   * All conditional expressions, including those based on types.
   */
  private final class FullConditionSchema extends PropertyConditionSchema {

    protected final String __when_type_assignable_1_class = null;

    protected final String __when_type_is_1_class = null;

    public FullConditionSchema(CompoundCondition parentCondition) {
      super(parentCondition);
    }

    protected Schema __when_type_assignable_begin(String className) {
      Condition cond = new ConditionWhenTypeAssignableTo(className);
      parentCondition.getConditions().add(cond);

      // No children allowed.
      return null;
    }

    protected Schema __when_type_is_begin(String className) {
      Condition cond = new ConditionWhenTypeIs(className);
      parentCondition.getConditions().add(cond);

      // No children allowed.
      return null;
    }

    @Override
    protected Schema subSchema(CompoundCondition cond) {
      return new FullConditionSchema(cond);
    }
  }

  private static final class IncludeExcludeSchema extends Schema {

    protected final String __exclude_1_name = null;

    protected final String __include_1_name = null;

    private final Set<String> excludes = new HashSet<String>();

    private final Set<String> includes = new HashSet<String>();

    public Set<String> getExcludes() {
      return excludes;
    }

    public Set<String> getIncludes() {
      return includes;
    }

    protected Schema __exclude_begin(String name) {
      excludes.add(name);
      return null;
    }

    protected Schema __include_begin(String name) {
      includes.add(name);
      return null;
    }
  }

  private static class LinkerName {
    public final String name;

    public LinkerName(String name) {
      this.name = name;
    }
  }

  /**
   * Converts a string into a linker name, validating it in the process.
   */
  private final class LinkerNameAttrCvt extends AttributeConverter {

    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {
      // Ensure the value is a valid Java identifier
      if (!Util.isValidJavaIdent(value)) {
        Messages.LINKER_NAME_INVALID.log(logger, value, null);
        throw new UnableToCompleteException();
      }

      // It is a valid name.
      return new LinkerName(value);
    }
  }

  /**
   * A dotted Java identifier or null. Zero-length names are represented as
   * null.
   */
  private static class NullableName {
    public final String token;

    public NullableName(String token) {
      this.token = token;
    }
  }

  /**
   * Converts a string into a nullable name, validating it in the process.
   */
  private final class NullableNameAttrCvt extends AttributeConverter {

    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {
      if (value == null || value.length() == 0) {
        return new NullableName(null);
      }

      // Ensure each part of the name is valid.
      //
      String[] tokens = (value + ". ").split("\\.");
      for (int i = 0; i < tokens.length - 1; i++) {
        String token = tokens[i];
        if (!Util.isValidJavaIdent(token)) {
          Messages.NAME_INVALID.log(logger, value, null);
          throw new UnableToCompleteException();
        }
      }

      // It is a valid name.
      //
      return new NullableName(value);
    }
  }

  /**
   * Converts property names into their corresponding property objects.
   */
  private final class PropertyAttrCvt extends AttributeConverter {
    private Class<? extends Property> concreteType;

    public PropertyAttrCvt(Class<? extends Property> concreteType) {
      this.concreteType = concreteType;
    }

    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {
      // Find the named property.
      //
      Property prop = moduleDef.getProperties().find(value);

      if (prop != null) {
        // Found it.
        //
        if (concreteType.isInstance(prop)) {
          return prop;
        }
        logger.log(TreeLogger.ERROR, "The specified property '"
            + prop.getName() + "' is not of the correct type; found '"
            + prop.getClass().getSimpleName() + "' expecting '"
            + concreteType.getSimpleName() + "'");
      } else {
        // Property not defined. This is a problem.
        //
        Messages.PROPERTY_NOT_FOUND.log(logger, value, null);
      }
      throw new UnableToCompleteException();
    }
  }

  /**
   * A limited number of conditional predicates based only on properties.
   */
  private class PropertyConditionSchema extends Schema {
    protected final String __when_property_is_1_name = null;

    protected final String __when_property_is_2_value = null;

    protected final CompoundCondition parentCondition;

    public PropertyConditionSchema(CompoundCondition parentCondition) {
      this.parentCondition = parentCondition;
    }

    protected Schema __all_begin() {
      CompoundCondition cond = new ConditionAll();
      parentCondition.getConditions().add(cond);
      return subSchema(cond);
    }

    protected Schema __any_begin() {
      CompoundCondition cond = new ConditionAny();
      parentCondition.getConditions().add(cond);
      return subSchema(cond);
    }

    protected Schema __none_begin() {
      CompoundCondition cond = new ConditionNone();
      parentCondition.getConditions().add(cond);
      return subSchema(cond);
    }

    /*
     * We intentionally use the BindingProperty type here for tough-love on
     * module writers. It prevents them from trying to create property providers
     * for unknown properties.
     */
    protected Schema __when_property_is_begin(BindingProperty prop,
        PropertyValue value) {
      Condition cond = new ConditionWhenPropertyIs(prop.getName(), value.token);
      parentCondition.getConditions().add(cond);

      // No children allowed.
      return null;
    }

    protected Schema subSchema(CompoundCondition cond) {
      return new PropertyConditionSchema(cond);
    }
  }

  private static class PropertyName {
    public final String token;

    public PropertyName(String token) {
      this.token = token;
    }
  }

  /**
   * Converts a string into a property name, validating it in the process.
   */
  private final class PropertyNameAttrCvt extends AttributeConverter {

    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {
      // Ensure each part of the name is valid.
      //
      String[] tokens = (value + ". ").split("\\.");
      for (int i = 0; i < tokens.length - 1; i++) {
        String token = tokens[i];
        if (!Util.isValidJavaIdent(token)) {
          Messages.PROPERTY_NAME_INVALID.log(logger, value, null);
          throw new UnableToCompleteException();
        }
      }

      // It is a valid name.
      //
      return new PropertyName(value);
    }
  }

  private static class PropertyValue {
    public final String token;

    public PropertyValue(String token) {
      this.token = token;
    }
  }

  /**
   * Converts a comma-separated string into an array of property value tokens.
   */
  private final class PropertyValueArrayAttrCvt extends AttributeConverter {
    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {
      String[] tokens = value.split(",");
      PropertyValue[] values = new PropertyValue[tokens.length];

      // Validate each token as we copy it over.
      //
      for (int i = 0; i < tokens.length; i++) {
        values[i] = (PropertyValue) propValueAttrCvt.convertToArg(schema, line,
            elem, attr, tokens[i]);
      }

      return values;
    }
  }

  /**
   * Converts a string into a property value, validating it in the process.
   */
  private final class PropertyValueAttrCvt extends AttributeConverter {
    public Object convertToArg(Schema schema, int line, String elem,
        String attr, String value) throws UnableToCompleteException {

      String token = value.trim();
      if (Util.isValidJavaIdent(token)) {
        return new PropertyValue(token);
      } else {
        Messages.PROPERTY_VALUE_INVALID.log(logger, token, null);
        throw new UnableToCompleteException();
      }
    }
  }

  private static class ScriptSchema extends Schema {

    private StringBuffer script;

    private int startLineNumber = -1;

    public ScriptSchema() {
    }

    public void __text(String text) {
      if (script == null) {
        script = new StringBuffer();
        startLineNumber = getLineNumber();
      }
      script.append(text);
    }

    public String getScript() {
      return script != null ? script.toString() : null;
    }

    public int getStartLineNumber() {
      return startLineNumber;
    }
  }

  /**
   * Map of property names to the modules that defined them explicitly using
   * <define-configuration-property>, used to generate warning messages.
   */
  private static final HashMap<String, String> propertyDefinitions = new HashMap<String, String>();

  /**
   * Map of property names to the modules that defined them implicitly using
   * <set-configuration-property>, used to generate warning messages.
   */
  private static final HashMap<String, String> propertySettings = new HashMap<String, String>();

  private static void addPrefix(String[] strings, String prefix) {
    for (int i = 0; i < strings.length; ++i) {
      strings[i] = prefix + strings[i];
    }
  }

  /**
   * Returns <code>true</code> if the string equals "true" or "yes" using a
   * case insensitive comparison.
   */
  private static boolean toPrimitiveBoolean(String s) {
    return "yes".equalsIgnoreCase(s) || "true".equalsIgnoreCase(s);
  }

  protected final String __module_1_rename_to = "";
  private final PropertyAttrCvt bindingPropAttrCvt = new PropertyAttrCvt(
      BindingProperty.class);
  private final BodySchema bodySchema;
  private final ClassAttrCvt classAttrCvt = new ClassAttrCvt();
  private final PropertyAttrCvt configurationPropAttrCvt = new PropertyAttrCvt(
      ConfigurationProperty.class);
  private boolean foundAnyPublic;
  private boolean foundExplicitSourceOrSuperSource;
  private final JsProgram jsPgm = new JsProgram();
  private final LinkerNameAttrCvt linkerNameAttrCvt = new LinkerNameAttrCvt();
  private final ModuleDefLoader loader;
  private final TreeLogger logger;
  private final ModuleDef moduleDef;
  private final String moduleName;
  private final String modulePackageAsPath;
  private final URL moduleURL;
  private final NullableNameAttrCvt nullableNameAttrCvt = new NullableNameAttrCvt();
  private final PropertyNameAttrCvt propNameAttrCvt = new PropertyNameAttrCvt();
  private final PropertyValueArrayAttrCvt propValueArrayAttrCvt = new PropertyValueArrayAttrCvt();
  private final PropertyValueAttrCvt propValueAttrCvt = new PropertyValueAttrCvt();

  public ModuleDefSchema(TreeLogger logger, ModuleDefLoader loader,
      String moduleName, URL moduleURL, String modulePackageAsPath,
      ModuleDef toConfigure) {
    this.logger = logger;
    this.loader = loader;
    this.moduleName = moduleName;
    this.moduleURL = moduleURL;
    this.modulePackageAsPath = modulePackageAsPath;
    assert (modulePackageAsPath.endsWith("/") || modulePackageAsPath.equals(""));
    this.moduleDef = toConfigure;
    this.bodySchema = new BodySchema();

    registerAttributeConverter(PropertyName.class, propNameAttrCvt);
    registerAttributeConverter(BindingProperty.class, bindingPropAttrCvt);
    registerAttributeConverter(ConfigurationProperty.class,
        configurationPropAttrCvt);
    registerAttributeConverter(PropertyValue.class, propValueAttrCvt);
    registerAttributeConverter(PropertyValue[].class, propValueArrayAttrCvt);
    registerAttributeConverter(LinkerName.class, linkerNameAttrCvt);
    registerAttributeConverter(NullableName.class, nullableNameAttrCvt);
    registerAttributeConverter(Class.class, classAttrCvt);
  }

  @SuppressWarnings("unused")
  protected Schema __module_begin(NullableName renameTo) {
    return bodySchema;
  }

  protected void __module_end(NullableName renameTo) {
    // Maybe infer source and public.
    //
    if (!foundExplicitSourceOrSuperSource) {
      bodySchema.addSourcePackage(modulePackageAsPath, "client", Empty.STRINGS,
          Empty.STRINGS, true, true, false);
    }

    if (!foundAnyPublic) {
      bodySchema.addPublicPackage(modulePackageAsPath, "public", Empty.STRINGS,
          Empty.STRINGS, true, true);
    }

    // We do this in __module_end so this value is never inherited
    moduleDef.setNameOverride(renameTo.token);
  }

  /**
   * Parses handwritten JavaScript found in the module xml, logging an error
   * message and throwing an exception if there's a problem.
   * 
   * @param startLineNumber the start line number where the script was found;
   *          used to report errors
   * @param script the JavaScript to wrap in "function() { script }" to parse
   * @return the parsed function
   * @throws UnableToCompleteException
   */
  private JsFunction parseJsBlock(int startLineNumber, String script)
      throws UnableToCompleteException {
    script = "function() { " + script + "}";
    StringReader r = new StringReader(script);
    List<JsStatement> stmts;
    try {
      // TODO Provide more context here
      stmts = JsParser.parse(jsPgm.createSourceInfo(startLineNumber,
          moduleURL.toExternalForm()), jsPgm.getScope(), r);
    } catch (IOException e) {
      logger.log(TreeLogger.ERROR, "Error reading script source", e);
      throw new UnableToCompleteException();
    } catch (JsParserException e) {
      SourceDetail dtl = e.getSourceDetail();
      if (dtl != null) {
        StringBuffer sb = new StringBuffer();
        sb.append(moduleURL.toExternalForm());
        sb.append("(");
        sb.append(dtl.getLine());
        sb.append(", ");
        sb.append(dtl.getLineOffset());
        sb.append("): ");
        sb.append(e.getMessage());
        logger.log(TreeLogger.ERROR, sb.toString(), e);
      } else {
        logger.log(TreeLogger.ERROR, "Error parsing JavaScript source", e);
      }
      throw new UnableToCompleteException();
    }

    // Rip the body out of the parsed function and attach the JavaScript
    // AST to the method.
    //
    JsFunction fn = (JsFunction) ((JsExprStmt) stmts.get(0)).getExpression();
    return fn;
  }

}
// CHECKSTYLE_NAMING_ON
