/**
* Copyright (c) 2011 Cloudsmith Inc. and other contributors, as listed below.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* Cloudsmith
*
*/
package org.cloudsmith.geppetto.pp.dsl.serialization;
import java.util.Collections;
import java.util.Map;
import org.eclipse.emf.ecore.EObject;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.IGrammarAccess;
import org.eclipse.xtext.RuleCall;
import org.eclipse.xtext.nodemodel.INode;
import org.eclipse.xtext.nodemodel.impl.AbstractNode;
import org.eclipse.xtext.parsetree.reconstr.impl.ValueSerializer;
import org.eclipse.xtext.util.Exceptions;
import org.eclipse.xtext.util.PolymorphicDispatcher;
import org.eclipse.xtext.util.PolymorphicDispatcher.ErrorHandler;
import com.google.common.collect.Maps;
import com.google.inject.Inject;
/**
* TODO: Can probably be simplified further as there is less need for the fancy overrides required for the
* Xtext 1.0 implementation.
* TODO: This class can probably be removed - with the change in dollarVar parsing there is nothing left it needs to do.
*
*/
public class PPValueSerializer extends ValueSerializer {
// private PPGrammarAccess pga;
private Map<AbstractRule, String> ruleToText;
private final PolymorphicDispatcher<String> unassignedDispatch = new PolymorphicDispatcher<String>(
"unassigned", 2, 3, Collections.singletonList(this), new ErrorHandler<String>() {
public String handle(Object[] params, Throwable e) {
return handleError(params, e);
}
});
@Inject
public PPValueSerializer(IGrammarAccess ga) {
// pga = (PPGrammarAccess) ga;
/**
* Map of terminals and keywords that the serializer can not automatically figure out
* how to handle. Adding a mapping to "ruleToText" will ensure that a call from a rule to
* the mapped rule will serialize as the mapped string throughout the grammar. If something more
* specific is required, a polymorphic "unassigned" method for the specific class should be added.
* Note that keywords in the grammar are handled automatically (unless nested in a data rule ?).
*/
ruleToText = Maps.newHashMap();
// ruleToText.put(pga.getDQT_DOLLARRule(), "$");
// ruleToText.put(pga.getDQT_QUOTERule(), "\"");
}
public String doUnassigned(EObject context, RuleCall ruleCall, INode node) {
if(node == null)
return unassignedDispatch.invoke(context, ruleCall);
return unassignedDispatch.invoke(context, ruleCall, node);
}
protected String handleError(Object[] params, Throwable e) {
return Exceptions.throwUncheckedException(e);
}
@Override
public String serializeUnassignedValue(EObject context, RuleCall ruleCall, INode node) {
try {
// let the super impl have a go at finding what to serialize, if it fails, check if
// the pp-specific rules knows better
return super.serializeUnassignedValue(context, ruleCall, node);
}
catch(IllegalArgumentException e) {
return doUnassigned(context, ruleCall, node);
}
}
public String unassigned(EObject o, RuleCall ruleCall) {
return unassigned(o, ruleCall, null);
}
public String unassigned(EObject o, RuleCall ruleCall, AbstractNode node) {
String s = ruleToText.get(ruleCall.getRule());
if(s != null)
return s;
throw new IllegalArgumentException("Undefined: unassigned rule call to Rule: " + ruleCall.getRule().getName());
}
}