All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.eclipse.xtext.conversion.impl.AbstractLexerBasedConverter Maven / Gradle / Ivy

There is a newer version: 2.4.3
Show newest version
/*******************************************************************************
 * Copyright (c) 2010 itemis AG (http://www.itemis.eu) and others.
 * 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
 *******************************************************************************/
package org.eclipse.xtext.conversion.impl;

import java.util.Map;

import org.antlr.runtime.ANTLRStringStream;
import org.antlr.runtime.Token;
import org.antlr.runtime.TokenSource;
import org.eclipse.xtext.AbstractRule;
import org.eclipse.xtext.conversion.IValueConverter;
import org.eclipse.xtext.conversion.ValueConverterException;
import org.eclipse.xtext.parser.antlr.ITokenDefProvider;
import org.eclipse.xtext.parser.antlr.Lexer;
import org.eclipse.xtext.parser.antlr.LexerBindings;

import com.google.inject.Inject;
import com.google.inject.Provider;
import com.google.inject.name.Named;

/**
 * @author Sebastian Zarnekow - Initial contribution and API
 */
public abstract class AbstractLexerBasedConverter extends AbstractValueConverter implements IValueConverter.RuleSpecific {

	@Inject(optional=true)
	@Named(LexerBindings.RUNTIME)
	private Provider lexerProvider;
	
	@Inject
	private ITokenDefProvider tokenDefProvider;

	private AbstractRule rule;
	
	public String toString(T value) {
		assertValidValue(value);
		String result = toEscapedString(value);
		TokenSource tokenSource = getTokenSource(result);
		assertTokens(value, tokenSource, result);
		return result;
	}

	protected void assertTokens(T value, TokenSource tokenSource, String escapedString) {
		if (tokenSource == null)
			return;
		Token token = tokenSource.nextToken();
		if (!escapedString.equals(token.getText())) {
			throw createTokenContentMismatchException(value, escapedString, token);
		}
		if (!getRuleName().toUpperCase().equals(getRuleName(token))) {
			throw createTokenTypeMismatchException(value, escapedString, token);
		}
		T reparsedValue = toValue(token.getText(), null);
		if (value != reparsedValue && !value.equals(reparsedValue)) {
			throw createTokenContentMismatchException(value, escapedString, token);
		}
	}

	protected ValueConverterException createTokenTypeMismatchException(T value, String escapedString, Token token) {
		return new ValueConverterException("The value '" + value + "' is an invalid " + getRuleName(), null, null);
	}

	protected ValueConverterException createTokenContentMismatchException(T value, String escapedString, Token token) {
		return new ValueConverterException("The value '" + value + "' is an invalid " + getRuleName(), null, null);
	}

	protected TokenSource getTokenSource(String escapedValue) {
		Lexer result = getLexer();
		if (result == null)
			return null;
		result.setCharStream(new ANTLRStringStream(escapedValue));
		return result;
	}

	protected void assertValidValue(T value) {
		if (value == null) {
			throw new ValueConverterException(getRuleName() + " may not be null.", null, null);
		}
	}
	
	protected String getRuleName() {
		return getRule().getName();
	}
	
	protected String toEscapedString(T value) {
		return value.toString();
	}
	
	protected Lexer getLexer() {
		if (lexerProvider != null)
			return lexerProvider.get();
		return null;
	}
	
	// TODO: rename to getLexerRuleName() on next API change
	protected String getRuleName(Token token) {
		String result = getTokenDefMap().get(token.getType());
		return result.substring("RULE_".length());
	}

	protected Map getTokenDefMap() {
		return tokenDefProvider.getTokenDefMap();
	}
	
	protected AbstractRule getRule() {
		return rule;
	}
	
	public void setRule(AbstractRule rule) {
		this.rule = rule;
	}
	
	public void setLexerProvider(Provider lexerProvider) {
		this.lexerProvider = lexerProvider;
	}
	
	public void setTokenDefProvider(ITokenDefProvider tokenDefProvider) {
		this.tokenDefProvider = tokenDefProvider;
	}
	
	protected ITokenDefProvider getTokenDefProvider() {
		return tokenDefProvider;
	}
	
	protected Provider getLexerProvider() {
		return lexerProvider;
	}
	
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy