Xtext editors for domain specific languages (DSLs) provide many error messages out of the box, such as syntactical errors, duplicate name errors or unresolvable references. For an improved user experience, some technical error messages from the editor (or, more 
specifically, from the Antlr parser that is used by the editor) may be customized. In many DSLs, identifiers (for DSL concepts like packages, entities and so on) are expected to conform to the regular expression of the terminal rule ID:
terminal ID : '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;In addition, any keyword that is defined in other rules of the DSL grammar may not be used as an identifier
package package // the second word is a reserved keyword and therefore not be valid as identifier
package ^package // okay, the keyword was escaped
package myPackage // okay unless 'myPackage' is a grammar keyword
The default 
error message when using a reserved keyword where an identifier is 
expected looks like this.
mismatched input 'package' expecting RULE_ID
This  message can be customized using Xtext's 
SyntaxErrorMessageProvider (written in 
Xtend):
| class SyntaxErrorMessageProviderCustom extends SyntaxErrorMessageProvider {
 public static val String USED_RESERVED_KEYWORD = "USED_RESERVED_KEYWORD"
 
 @Inject IGrammarAccess grammarAccess
 /**
 * Customized error message for reserved keywords
 */
 override getSyntaxErrorMessage(IParserErrorContext context) {
 val unexpectedText = context?.recognitionException?.token?.text
 if (GrammarUtil::getAllKeywords(grammarAccess.getGrammar()).contains(unexpectedText)) {
 println(context.defaultMessage)
 return new SyntaxErrorMessage('''
 "«unexpectedText»" is a reserved keyword which is not allowed as Identifier.
 Please choose another word or alternatively confuse your co-workers by escaping it with the caret (^) character like this: "^«unexpectedText»".''',
 USED_RESERVED_KEYWORD)
 }
 super.getSyntaxErrorMessage(context)
 }
 }
 
 | 
 
 
 
 
The customized error message provider has to be bound in 
MyDslRuntimeModule.java like this
:
| /*** custom error messages for syntax errors
 */
 public Class<X extends ISyntaxErrorMessageProvider> bindISyntaxErrorMessageProvider() {
 return SyntaxErrorMessageProviderCustom.class;
 }
 
 | 
 
 
 
 
A simple quickfix in 
MyDslQuickfixProvider could look like this:
| 
 /*** Provide a fix when reserved keywords are used as identifiers
 */
 @Fix(SyntaxErrorMessageProviderCustom::USED_RESERVED_KEYWORD)
 def public void reservedKeywordUsed(Issue issue, IssueResolutionAcceptor acceptor) {
 val unexpectedText = issue.data?.get(0)
 acceptor.accept(issue, '''Change '«unexpectedText»' to '«unexpectedText.generateUniqueIdentifier».' ''', '''
 Change '«unexpectedText»' to '«unexpectedText.generateUniqueIdentifier»',
 which is not a reserved keyword.''',
 "correction_linked_rename.gif",
 [ IModificationContext context |
 val xtextDocument = context.getXtextDocument
 xtextDocument.replace(issue.offset, issue.length, unexpectedText.generateUniqueIdentifier)
 ])
 }
 
 def String generateUniqueIdentifier(String it) {
 val candidate = 'my' + it?.toFirstUpper?:'Name'
 var count = 1
 val reserved = GrammarUtil::getAllKeywords(grammarAccess.getGrammar())
 if (reserved.contains(candidate)) {
 while (reserved.contains(candidate + count)) {
 count = count + 1
 }
 return candidate + count
 }
 return candidate
 }
 
 | 
 
 
 
 
This kind of customization has been available for a long time now. For more information, see 
Customizing error messages from Sebastian Zarnekow.