/*
 * 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.core.ext.linker.PropertyProviderGenerator;
import com.google.gwt.dev.js.JsParser;
import com.google.gwt.dev.js.JsParserException;
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.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.regex.Pattern;

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

  private final class BodySchema extends Schema {

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __add_linker_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __clear_configuration_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __collapse_all_properties_1_value = "true";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __collapse_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __collapse_property_2_values = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __define_configuration_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __define_configuration_property_2_is_multi_valued = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __define_linker_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __define_linker_2_class = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __define_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __define_property_2_values = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __entry_point_1_class = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __extend_configuration_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __extend_configuration_property_2_value = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __extend_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __extend_property_2_values = null;

    @SuppressWarnings("unused") // referenced reflectively ($ means optional)
    protected final String __extend_property_3_fallback_value$ = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __generate_with_1_class = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __inherits_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __property_provider_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __property_provider_2_generator = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __public_1_path = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __public_2_includes = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __public_3_excludes = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __public_4_skips = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __public_5_defaultexcludes = "yes";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __public_6_casesensitive = "true";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __replace_with_1_class = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __script_1_src = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __servlet_1_path = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __servlet_2_class = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __set_configuration_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __set_configuration_property_2_value = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __set_property_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __set_property_2_value = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __set_property_fallback_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __set_property_fallback_2_value = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __source_1_path = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __source_2_includes = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __source_3_excludes = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __source_4_skips = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __source_5_defaultexcludes = "yes";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __source_6_casesensitive = "true";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __stylesheet_1_src = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __super_source_1_path = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __super_source_2_includes = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __super_source_3_excludes = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __super_source_4_skips = "";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __super_source_5_defaultexcludes = "yes";

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __super_source_6_casesensitive = "true";

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

    private Schema fChild;

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __collapse_all_properties_begin(boolean collapse) {
      moduleDef.setCollapseAllProperties(collapse);
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __collapse_property_begin(PropertyName name,
        PropertyValueGlob[] values) throws UnableToCompleteException {
      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 BindingProperty)) {
        logger.log(TreeLogger.ERROR, "The property " + name.token
            + " is not a deferred-binding property");
        throw new UnableToCompleteException();
      }

      BindingProperty binding = (BindingProperty) prop;
      List<String> allowed = Arrays.asList(binding.getDefinedValues());

      String[] tokens = new String[values.length];
      boolean error = false;
      for (int i = 0, j = values.length; i < j; i++) {
        tokens[i] = values[i].token;
        if (values[i].isGlob()) {
          // Expanded later in BindingProperty
          continue;
        } else if (!allowed.contains(tokens[i])) {
          logger.log(TreeLogger.ERROR, "The value " + tokens[i]
              + " was not previously defined for the property "
              + binding.getName());
          error = true;
        }
      }

      if (error) {
        throw new UnableToCompleteException();
      }

      binding.addCollapsedValues(tokens);

      // No children
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __entry_point_begin(String className) {
      moduleDef.addEntryPointTypeName(className);
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __extend_property_begin(BindingProperty property,
        PropertyValue[] values, PropertyFallbackValue fallbackValue) 
        throws UnableToCompleteException {
      for (int i = 0; i < values.length; i++) {
        property.addDefinedValue(property.getRootCondition(), values[i].token);
      }

      // validate fallback-property value if present
      if (fallbackValue != null) {
        if (!property.isDefinedValue(fallbackValue.token)) {
        logger.log(TreeLogger.ERROR, "The property " + property.name
            + " fallback-value was not defined");
        throw new UnableToCompleteException(); 
        }
        // add fallback map to the property
        for (int i = 0; i < values.length; i++) {
          property.addFallbackValue(values[i].token, fallbackValue.token);
        }
      }
     
      // No children.
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __fail_begin() {
      RuleFail rule = new RuleFail();
      moduleDef.getRules().prepend(rule);
      return new FullConditionSchema(rule.getRootCondition());
    }

    @SuppressWarnings("unused") // called reflectively
    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());
    }

    @SuppressWarnings("unused") // called reflectively
    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") // called reflectively
    protected Schema __property_provider_begin(BindingProperty property,
        Class<? extends PropertyProviderGenerator> generator) {
      fChild = new ScriptSchema();
      return fChild;
    }

    @SuppressWarnings("unused") // called reflectively
    protected void __property_provider_end(BindingProperty property,
        Class<? extends PropertyProviderGenerator> generator)
        throws UnableToCompleteException {
      if (generator != null
          && !PropertyProviderGenerator.class.isAssignableFrom(generator)) {
        logger.log(TreeLogger.ERROR, "A property provider generator must "
            + "extend " + PropertyProviderGenerator.class.getName(), null);
        throw new UnableToCompleteException();
      }
      ScriptSchema childSchema = ((ScriptSchema) fChild);
      String script = childSchema.getScript();
      property.setProviderGenerator(generator);
      if (script == null) {
        if (generator == null) {
          // This is a problem.
          //
          logger.log(TreeLogger.ERROR, "Property providers must specify a "
              + "JavaScript body or a provider generator", null);
          throw new UnableToCompleteException();
        }
      } else {
        int lineNumber = childSchema.getStartLineNumber();
        JsFunction fn = parseJsBlock(lineNumber, script);
        property.setProvider(new PropertyProvider(fn.getBody().toSource()));
      }
    }

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

    @SuppressWarnings("unused") // called reflectively
    protected void __public_end(String path, String includes, String excludes,
        String skips, 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()]);

      Set<String> skipSet = childSchema.getSkips();
      addDelimitedStringToSet(skips, "[ ,]", skipSet);
      String[] skipList = skipSet.toArray(new String[skipSet.size()]);

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

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

    @SuppressWarnings("unused") // called reflectively
    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") // called reflectively
    protected Schema __script_begin(String src) {
      return fChild = new ScriptSchema();
    }

    @SuppressWarnings("unused") // called reflectively
    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 use an associated JavaScript block; ignoring.",
            null);
      }
      moduleDef.getScripts().append(new Script(src));
    }

    @SuppressWarnings("unused") // called reflectively
    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;
    }

    @SuppressWarnings("unused") // called reflectively
    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") // called reflectively
    protected Schema __set_property_begin(BindingProperty prop,
        PropertyValue[] value) throws UnableToCompleteException {
      bindingPropertyCondition = new ConditionAll();
      return new PropertyConditionSchema(bindingPropertyCondition);
    }

    @SuppressWarnings("unused") // called reflectively
    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);
    }

    @SuppressWarnings("unused") // called reflectively
    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") // called reflectively
    protected Schema __source_begin(String path, String includes,
        String excludes, String skips, String defaultExcludes,
        String caseSensitive) {
      return fChild = new IncludeExcludeSchema();
    }

    @SuppressWarnings("unused") // called reflectively
    protected void __source_end(String path, String includes, String excludes,
        String skips, String defaultExcludes, String caseSensitive) {
      addSourcePackage(path, includes, excludes, skips, 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
     */
    @SuppressWarnings("unused") // called reflectively
    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") // called reflectively
    protected Schema __super_source_begin(String path, String includes,
        String excludes, String skips, String defaultExcludes,
        String caseSensitive) {
      return fChild = new IncludeExcludeSchema();
    }

    @SuppressWarnings("unused") // called reflectively
    protected void __super_source_end(String path, String includes,
        String excludes, String skips, String defaultExcludes,
        String caseSensitive) {
      addSourcePackage(path, includes, excludes, skips, 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, String[] skipList,
        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, skipList,
          defaultExcludes, caseSensitive);
    }

    private void addSourcePackage(String relDir, String includes,
        String excludes, String skips, 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()]);

      Set<String> skipSet = childSchema.getSkips();
      addDelimitedStringToSet(skips, "[ ,]", skipSet);
      String[] skipList = skipSet.toArray(new String[skipSet.size()]);

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

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

    private void addSourcePackage(String modulePackagePath, String relDir,
        String[] includeList, String[] excludeList, String[] skipList,
        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, skipList, defaultExcludes, caseSensitive);
      } else {
        /*
         * Add the full package path to the include/exclude/skip lists since the
         * logical name of classes on the source path includes the package path
         * but the include, exclude, and skip lists do not.
         */
        addPrefix(includeList, fullPackagePath);
        addPrefix(excludeList, fullPackagePath);
        addPrefix(skipList, fullPackagePath);

        moduleDef.addSourcePackage(fullPackagePath, includeList, excludeList,
            skipList, 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 {
      if (value.length() == 0) {
        // handle optional class names
        return null;
      }
      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 {

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __when_type_assignable_1_class = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __when_type_is_1_class = null;

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

    @SuppressWarnings("unused") // called reflectively
    protected Schema __when_type_assignable_begin(String className) {
      Condition cond = new ConditionWhenTypeAssignableTo(className);
      parentCondition.getConditions().add(cond);

      // No children allowed.
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    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 {

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __exclude_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __include_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __skip_1_name = null;

    /**
     * Files neither in this module, nor available from other modules.
     */
    private final Set<String> excludes = new HashSet<String>();

    /**
     * Files in this module.
     */
    private final Set<String> includes = new HashSet<String>();

    /**
     * Files not in this module, but available from other modules.
     */
    private final Set<String> skips = new HashSet<String>();

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

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

    public Set<String> getSkips() {
      return skips;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __exclude_begin(String name) {
      excludes.add(name);
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __include_begin(String name) {
      includes.add(name);
      return null;
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __skip_begin(String name) {
      skips.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 {

    @Override
    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 {

    @Override
    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;
    }

    @Override
    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 {
    @SuppressWarnings("unused") // referenced reflectively
    protected final String __when_linker_added_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __when_property_is_1_name = null;

    @SuppressWarnings("unused") // referenced reflectively
    protected final String __when_property_is_2_value = null;

    protected final CompoundCondition parentCondition;

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

    @SuppressWarnings("unused") // called reflectively
    protected Schema __all_begin() {
      CompoundCondition cond = new ConditionAll();
      parentCondition.getConditions().add(cond);
      return subSchema(cond);
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __any_begin() {
      CompoundCondition cond = new ConditionAny();
      parentCondition.getConditions().add(cond);
      return subSchema(cond);
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __none_begin() {
      CompoundCondition cond = new ConditionNone();
      parentCondition.getConditions().add(cond);
      return subSchema(cond);
    }

    @SuppressWarnings("unused") // called reflectively
    protected Schema __when_linker_added_begin(LinkerName linkerName) {
      Condition cond = new ConditionWhenLinkerAdded(linkerName.name);
      parentCondition.getConditions().add(cond);

      // No children allowed.
      return null;
    }

    /*
     * 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.
     */
    @SuppressWarnings("unused") // called reflectively
    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 {

    @Override
    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;
    }
  }

  private static class PropertyFallbackValue {
    public final String token;

    public PropertyFallbackValue(String token) {
      this.token = token;
    }
  }
  
  /**
   * Converts a comma-separated string into an array of property value tokens.
   */
  private final class PropertyValueArrayAttrCvt extends AttributeConverter {
    @Override
    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 {
    @Override
    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 PropertyValueGlob {
    public final String token;

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

    public boolean isGlob() {
      return token.contains(BindingProperty.GLOB_STAR);
    }
  }

  /**
   * Converts a string into a property fallback value, validating it in the process.
   */
  private final class PropertyFallbackValueAttrCvt extends AttributeConverter {
    @Override
    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 PropertyFallbackValue(token);
      } else {
        Messages.PROPERTY_VALUE_INVALID.log(logger, token, null);
        throw new UnableToCompleteException();
      }
    }
  }

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

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

      return values;
    }
  }

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

      String token = value.trim();
      String tokenNoStar = token.replaceAll(
          Pattern.quote(BindingProperty.GLOB_STAR), "");
      if (BindingProperty.GLOB_STAR.equals(token)
          || Util.isValidJavaIdent(tokenNoStar)) {
        return new PropertyValueGlob(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() {
    }

    @SuppressWarnings("unused") // called reflectively
    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();
  private final PropertyFallbackValueAttrCvt propFallbackValueAttrCvt = new PropertyFallbackValueAttrCvt();
  private final PropertyValueGlobArrayAttrCvt propValueGlobArrayAttrCvt = new PropertyValueGlobArrayAttrCvt();
  private final PropertyValueGlobAttrCvt propValueGlobAttrCvt = new PropertyValueGlobAttrCvt();

  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(PropertyFallbackValue.class, propFallbackValueAttrCvt);
    registerAttributeConverter(PropertyValue[].class, propValueArrayAttrCvt);
    registerAttributeConverter(PropertyValueGlob.class, propValueGlobAttrCvt);
    registerAttributeConverter(PropertyValueGlob[].class,
        propValueGlobArrayAttrCvt);
    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, Empty.STRINGS, true, true, false);
    }

    if (!foundAnyPublic) {
      bodySchema.addPublicPackage(modulePackageAsPath, "public", Empty.STRINGS,
          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) {
      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
