SlideShare a Scribd company logo
Moritz Eysholdt, itemis AG
Serializing EMF
models with Xtext
Xtextcon 2014!
Kiel, Germany
Agenda
❖ Parsing vs. Serializing!
❖ Use Cases!
❖ Generating vs. Serializing!
❖ Challenges!
❖ The Contract!
❖ Architecture!
❖ Hooks!
❖ Advice
The New and the Old Serializer
org.eclipse.xtext.serializer	
•The New Serializer. This presentation is about it.
org.eclipse.xtext.parsetree.reconstr	
•The Old Serializer. Don’t used it.!
•Cryptic Error Messages!
•Bad Performance for Large Models!
•marked @Deprecated
Parser vs. Serializer
XtextResource
ModelModelTextual!
Model
Parser
Serializer
load()
save()
Parser vs. Serializer
XtextResource
ModelModelTextual!
Model
AST
Parser
Serializer
load()
save()
Use Cases
Quickfix
Refactoring
Non-Textual !
Editors
Non-Textual!
Persistence
Generators
Use Cases
Quickfix
Refactoring
Non-Textual !
Editors
Non-Textual!
Persistence
Generators
Use Cases
Quickfix
Non-Textual !
Editors
Non-Textual!
Persistence
Generators
Refactoring
Use Cases
Quickfix
Non-Textual!
Persistence
Generators
Refactoring
Non-Textual !
Editors
EMF Store
<?XML?>
<?XMI?>
Use Cases
Quickfix
Non-Textual!
Persistence
Generators
Refactoring
Non-Textual !
Editors
Read
Transform
Serialize
Generate, Transpile, Compile, Migrate…
Why Serialize?
❖ object model usually easier to modify than
its textual representation!
❖ guaranteed syntactical correctness!
❖ automatic handling of comments!
❖ automatic handling of whitespace
…when I have Xtend, THE language for generators
When not to Serialize
❖ Avoid serializing models that are broken due
to parse errors.!
❖ Template languages are simpler when
writing out large text chunks that never
change.
The hard Contract
Parsing a serialized Model must result !
in a model equal to the original.
Model original = createModel()	
String serialized = serialize(original)	
Model parsed = parse(serialized)	
assertEqual(original, parsed)
…enables textual models as persistence format
The soft Contract
Serializing a model that has been modified after parsing!
should only change the smallest number of characters necessary.
…keep diffs small
String originalDoc = loadDocument()	
Model parsed = parse(originalDoc)	
Model modified = applyModifications(parsed)	
String newDoc = serialize(modified)	
int numberOfChars = diff(originalDoc, newDoc).size()
1. Keep textual diffs small.!
2. Strictly comply with the semantic model!
3. Loosely comply with the node model
Challenges
❖ unassigned elements!
❖ ambiguous mapping from EStructuralFeatures to Assignments!
❖ ambiguous mapping from EClasses to ParserRules and Actions
…because the AST is actually abstract, as in “lack of information”
API Frontends #1
package org.eclipse.xtext.resource;	
!
public class XtextResource extends ResourceImpl {	
!
	 (…)	
!
	 public void save(Map<?, ?> options) 	
	 	 throws IOException {}	
!
	 public final void save(OutputStream outputStream, Map<?, ?> options) 	
	 	 throws IOException {}	
}
API Frontends #2
package org.eclipse.xtext.serializer;	
!
@ImplementedBy(Serializer.class)	
public interface ISerializer {	
	 public String serialize(EObject obj);	
	 public String serialize(EObject obj, SaveOptions options);	
	 public void serialize(EObject obj, Writer writer, SaveOptions options)	
	 	 throws IOException;	
	 public ReplaceRegion serializeReplacement(EObject obj, SaveOptions options);	
}
Options:!
- format: !
- true: format all!
- false: format regions without whitespace information!
- validate: don’t use, it’s an old algorithm.
Before Serialization
Create one State Machine per Context per EClass
Root:	
	 "optional"? ID children+=(List | Path);	
!
List returns Child:	
	 "list" item+=ID ("," item+=ID)*;	
!
Path returns Child:	
	 "path" seg=ID ({Segment.parent=current} seg=ID)+;
Context EClass
Root Root
List Child
Path Segment
Path_Segment_2_0 Child
Path_Segment_2_0 Segment
During Serialization #1
Find right state machines and !
find right path through them
Root:	
"optional"? ID children+=(List | Path);	
!
List returns Child:	
"list" item+=ID ("," item+=ID)*;
Context EClass
Root Root
Context EClass
List Child
optional Foo list a, b, cOutput:
Architecture #3
Context EClass
Root Root
Context EClass
List Child
Context EClass
Root Root
Context EClass
List Child
Semantic!
assigned grammar elements
Syntactic!
unassigned grammar elements
optional Foo list a, b, cOutput:
Architecture #4: Observer
Semantic!
Sequencer
Syntactic!
Sequencer
HiddenToken!
Sequencer
Formatter Writer
Events
Listens To
assigend!
* RuleCalls!
* Terminals!
* DataTypes!
* Keywords!
* CrossRefs
unassigned!
* RuleCalls!
* Terminals!
* DataTypes!
* Keywords
* whitespace!
* comments
modifies!
whitespace
writes to !
stream
Output: /*X*/ Foo list a
Serializer HiddenTokenSequencerSyntacticSequencerSemanticSequencer
createSequence
(Root, Root)
enter
AssignedParserRuleCall
(children=List)
enter
AssignedParserRuleCall
(children=List)
createSequence
(List, Children)
accept
UnassignedRuleCall
(ID)
accept
AssignedTerminalRuleCall
(itemi=ID)
accept
Keyword
("list")
accept
AssignedTerminalRuleCall
(itemi=ID)
leave
AssignedParserRuleCall
(children=List)
leave
AssignedParserRuleCall
(children=List)
Formatter Writer
enterAssignedParserRuleCall()
acceptWhitespace()
acceptWhitespace()
acceptComment(/*X*/)
acceptUnassignedRuleCall()
acceptKeyword()
acceptWhitespace()
acceptAssignedTerminalRuleCall()
acceptWhitespace()
enterAssignedParserRuleCall()
Root:	
"optional"? ID children+=(List | Path);
List returns Child:	
"list" item+=ID ("," item+=ID)*;
SerializerFragment
fragment = serializer.SerializerFragment auto-inject {	
generateStub = true	
// generateDebugData = true	
}
•SerializerFragment not required to use serializer!!
•Only purpose of SerializerFragment is to generate convenience API!
•generateDebugData to generate pretty state machine diagrams (graphviz dot)
Hooks #1: ITransientValueService
•selectively exclude model-objects and -values from serialization!
•transient == NOT serialized!
•Default setting from Ecore model: EStructuralFeature.isTransient()
public interface ITransientValueService {	
!
	 enum ListTransient {	
	 	 NO, SOME, YES	
	 }	
!
	 enum ValueTransient {	
	 	 NO, PREFERABLY, YES	
	 }	
!
	 public ListTransient isListTransient(EObject semanticObject, EStructuralFeature feature);	
!
	 public boolean isValueInListTransient(EObject semanticObject, int index, EStructuralFeature feature);	
!
	 public ValueTransient isValueTransient(EObject semanticObject, EStructuralFeature feature);	
}
Hooks #2: Token Serialization
public interface ICrossReferenceSerializer {	
	 boolean isValid(EObject context, CrossReference crossref, EObject target, INode node);	
	 String serializeCrossRef(EObject context, CrossReference crossref, EObject target, INode node);	
}
public interface IKeywordSerializer {	
	 boolean isValid(EObject context, Keyword keyword, Object value);	
	 String serializeAssignedKeyword(EObject context, Keyword keyword, Object value, INode node);	
}
public interface IValueSerializer {	
	 boolean isValid(EObject context, RuleCall ruleCall, Object value);	
	 String serializeAssignedValue(EObject context, RuleCall ruleCall, Object value, INode node);	
}
public interface IEnumLiteralSerializer {	
	 boolean isValid(EObject context, RuleCall ruleCall, Object value);	
	 String serializeAssignedEnumLiteral(EObject context, RuleCall ruleCall, Object value, INode node);	
}
Hooks #3: SemanticSequencer
class SerSipSemanticSequencer extends AbstractSerSipSemanticSequencer {	
!
	 @Inject SerSipGrammarAccess grammarAccess;	
!
	 /**	
	 * Constraint:	
	 * (children+=Path | children+=List)	
	 */	
	 override protected sequence_Root(EObject context, Root semanticObject) {	
	 	 val feeder = createSequencerFeeder(semanticObject)	
	 	 for (child : semanticObject.children) {	
	 	 	 if (child.seg != null) {	
	 	 	 	 feeder.accept(grammarAccess.rootAccess.childrenPathParserRuleCall_2_0_0, child)	
	 	 	 } else {	
	 	 	 	 feeder.accept(grammarAccess.rootAccess.childrenListParserRuleCall_2_0_1, child)	
	 	 	 }	
	 	 }	
	 	 feeder.finish()	
	 }	
}	
Root:	
	 "optional"? ID children+=(Path | List);	
!
List returns Child:	
	 "list" item+=ID ("," item+=ID)*;	
!
Path returns Child:	
	 "path" seg=ID ({Segment.parent=current} seg=ID)+;
Hooks #4: SyntacticSequencer
class SerSipSyntacticSequencer extends AbstractSerSipSyntacticSequencer {	
!
	 /**	
	 * terminal ID 		 : '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*;	
	 */	
	 override getIDToken(EObject semanticObject, RuleCall ruleCall, INode node) {	
	 	 if (node != null)	
	 	 	 return getTokenText(node);	
	 	 return "";	
	 }	
!
	 /**	
	 * Syntax:	
	 * 'optional'?	
	 */	
	 override emit_Root_OptionalKeyword_0_q(EObject semanticObject, ISynNavigable transition, List<INode> nodes) {	
	 	 acceptNodes(transition, nodes);	
	 }	
}
Root:	
	 "optional"? ID children+=(Path | List);
Understanding Ambiguities
•A grammar is ambiguous for the serializer if there can be more
than one textual syntax for a given model.!
!
•A grammar is ambiguous for the parser if there can be more than
one model for a given textual syntax1.
R1:	
foo=ID | bar=ID;
R2:	
(“foo” val=ID) | 	
(“bar” val=ID);
Does “a” parse
to or ?foo=a bar=b
Does serialize to
“foo b” or “bar b”?
val=b
parseserialize
1. that is not completely correct. A grammar is ambiguous when there is more than one path to
consume a given input. That, however, usually leads to different models.
Understanding Ambiguities
Root: 	
(foos=Foo | bars=Bar)*;	
!
Foo: 	
“foo” foo=ID;	
!
Bar: 	
“bar” bar=ID;
(1) . 	
(2) bar b foo a	
(3) foo a bar b
Root
foo=a bar=b
Does (1) serialize
to (2) or (3)?
Avoiding Ambiguities
Analysis: Grammars can be ambiguous for the serializer.!
!
Example:
Root: 	
(foos=Foo | bars=Bar)*;	
!
Foo: 	
“foo” foo=ID;	
!
Bar: 	
“bar” bar=ID;
Root: 	
members+=Member;	
!
Member:	
Foo | Bar;	
!
Foo: 	
“foo” foo=ID;	
!
Bar: 	
“bar” bar=ID;
•Single “member” list to maintain order!
•“Foo” and “Bar” extend “Member”!
•implement getFoo() and getBar() as filters on getMembers()
Avoid Unserializeable Models
The Xtext grammar can imply constraints on your model. !
!
Serialization is only possible if the model complies with theses
constraints because the grammar does not define syntax for models that
don’t comply. Examples:
GRAMMAR CONSTRAINT
R1: name=ID; name != null
R2: (name=ID | title=STING); (name != null) ^ (title != null)
R3: items+=ID+; items.size() >= 1
R4: (a+=ID b+=ID)*; a.size() == b.size()
Avoid Unserializeable Models
Solution:!
!
a) Ensure your grammar does not imply constraints. !
b) Ensure your TransientValueService prevents constraint violations.!
Implement Xtext Validation to enforce constraints.!
!
This will also improve your error messages but may make content assist
too chatty.
RESTRICTIVE SAFE
R1: name=ID;
R1: name=ID?;	
R1: (name=ID | “?”);
R2: (name=ID | title=STING); R2: name=ID? title=STING?;
R3: items+=ID+; R3: items+=ID*;
R4: (a+=ID b+=ID)*;
R4: (a+=ID b+=ID)*	
(“spareA={“ a+=ID+ “}”)?	
(“spareB={“ b+=ID+ “}”)?;
Configure Your Scope Right
You can (and need) to configure global scoping for a ResourceSet!
XtextLiveScopeResourceSetProviderXtextResourceSetProvider
ResourceSet
Dirty Editor State
Index
(default) (what you need)
<shadows>
<shadows>
Dirty Editor State
Index
<shadows>
Happy Serializing!

More Related Content

What's hot

Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines Reloaded
Roman Elizarov
 
Integrating Xtext Language Server support in Visual Studio Code
Integrating Xtext Language Server support in Visual Studio CodeIntegrating Xtext Language Server support in Visual Studio Code
Integrating Xtext Language Server support in Visual Studio Code
Karsten Thoms
 
Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
Bedis ElAchèche
 
NestJS
NestJSNestJS
NestJS
Wilson Su
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
Brainhub
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
Roman Elizarov
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
Nir Kaufman
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
Roman Elizarov
 
Typescript ppt
Typescript pptTypescript ppt
Typescript ppt
akhilsreyas
 
LINQ
LINQLINQ
Introducing type script
Introducing type scriptIntroducing type script
Introducing type script
Remo Jansen
 
Variable hoisting in JavaScript
Variable hoisting in JavaScriptVariable hoisting in JavaScript
Variable hoisting in JavaScript
Ideas2IT Technologies
 
Why TypeScript?
Why TypeScript?Why TypeScript?
Why TypeScript?
FITC
 
Getting started with typescript
Getting started with typescriptGetting started with typescript
Getting started with typescript
C...L, NESPRESSO, WAFAASSURANCE, SOFRECOM ORANGE
 
[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309
teddysoft
 
9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript
pcnmtutorials
 
Python Deserialization Attacks
Python Deserialization AttacksPython Deserialization Attacks
Python Deserialization Attacks
NSConclave
 
Cucumber and Spock Primer
Cucumber and Spock PrimerCucumber and Spock Primer
Cucumber and Spock Primer
John Ferguson Smart Limited
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
Ahmed Swilam
 

What's hot (20)

Kotlin Coroutines Reloaded
Kotlin Coroutines ReloadedKotlin Coroutines Reloaded
Kotlin Coroutines Reloaded
 
Integrating Xtext Language Server support in Visual Studio Code
Integrating Xtext Language Server support in Visual Studio CodeIntegrating Xtext Language Server support in Visual Studio Code
Integrating Xtext Language Server support in Visual Studio Code
 
Javascript essentials
Javascript essentialsJavascript essentials
Javascript essentials
 
NestJS
NestJSNestJS
NestJS
 
Introduction to RxJS
Introduction to RxJSIntroduction to RxJS
Introduction to RxJS
 
Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017Deep dive into Coroutines on JVM @ KotlinConf 2017
Deep dive into Coroutines on JVM @ KotlinConf 2017
 
Nestjs MasterClass Slides
Nestjs MasterClass SlidesNestjs MasterClass Slides
Nestjs MasterClass Slides
 
Rxjs ppt
Rxjs pptRxjs ppt
Rxjs ppt
 
Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017Introduction to Coroutines @ KotlinConf 2017
Introduction to Coroutines @ KotlinConf 2017
 
Typescript ppt
Typescript pptTypescript ppt
Typescript ppt
 
LINQ
LINQLINQ
LINQ
 
Introducing type script
Introducing type scriptIntroducing type script
Introducing type script
 
Variable hoisting in JavaScript
Variable hoisting in JavaScriptVariable hoisting in JavaScript
Variable hoisting in JavaScript
 
Why TypeScript?
Why TypeScript?Why TypeScript?
Why TypeScript?
 
Getting started with typescript
Getting started with typescriptGetting started with typescript
Getting started with typescript
 
[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309[教材] 例外處理設計與重構實作班201309
[教材] 例外處理設計與重構實作班201309
 
9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript9. ES6 | Let And Const | TypeScript | JavaScript
9. ES6 | Let And Const | TypeScript | JavaScript
 
Python Deserialization Attacks
Python Deserialization AttacksPython Deserialization Attacks
Python Deserialization Attacks
 
Cucumber and Spock Primer
Cucumber and Spock PrimerCucumber and Spock Primer
Cucumber and Spock Primer
 
Class 3 - PHP Functions
Class 3 - PHP FunctionsClass 3 - PHP Functions
Class 3 - PHP Functions
 

Viewers also liked

Codegeneration Goodies
Codegeneration GoodiesCodegeneration Goodies
Codegeneration Goodies
meysholdt
 
Parsing Expression With Xtext
Parsing Expression With XtextParsing Expression With Xtext
Parsing Expression With Xtext
Sven Efftinge
 
Future of Xtext
Future of XtextFuture of Xtext
Future of Xtext
Sven Efftinge
 
Turning Ideas Into Code Faster
Turning Ideas Into Code FasterTurning Ideas Into Code Faster
Turning Ideas Into Code Faster
meysholdt
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
Karsten Thoms
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
Dr. Jan Köhnlein
 
EMF - Beyond The Basics
EMF - Beyond The BasicsEMF - Beyond The Basics
EMF - Beyond The Basics
Dr. Jan Köhnlein
 
EMF Tips n Tricks
EMF Tips n TricksEMF Tips n Tricks
EMF Tips n Tricks
Kaniska Mandal
 
Xtend - A Language Made for Java Developers
Xtend - A Language Made for Java DevelopersXtend - A Language Made for Java Developers
Xtend - A Language Made for Java Developers
Sebastian Zarnekow
 
DSLs for Java Developers
DSLs for Java DevelopersDSLs for Java Developers
DSLs for Java Developers
Dr. Jan Köhnlein
 
Graphical Views For Xtext With FXDiagram
Graphical Views For Xtext With FXDiagramGraphical Views For Xtext With FXDiagram
Graphical Views For Xtext With FXDiagram
Dr. Jan Köhnlein
 
Graphical Views For Xtext
Graphical Views For XtextGraphical Views For Xtext
Graphical Views For Xtext
Dr. Jan Köhnlein
 
Jazoon 2010 - Building DSLs with Eclipse
Jazoon 2010 - Building DSLs with EclipseJazoon 2010 - Building DSLs with Eclipse
Jazoon 2010 - Building DSLs with Eclipse
Peter Friese
 
Enhancing Xtext for General Purpose Languages
Enhancing Xtext for General Purpose LanguagesEnhancing Xtext for General Purpose Languages
Enhancing Xtext for General Purpose Languages
University of York
 
Eclipse DemoCamp in Paris: Language Development with Xtext
Eclipse DemoCamp in Paris: Language Development with XtextEclipse DemoCamp in Paris: Language Development with Xtext
Eclipse DemoCamp in Paris: Language Development with XtextSebastian Zarnekow
 
From Stairway to Heaven onto the Highway to Hell with Xtext
From Stairway to Heaven onto the Highway to Hell with XtextFrom Stairway to Heaven onto the Highway to Hell with Xtext
From Stairway to Heaven onto the Highway to Hell with Xtext
Karsten Thoms
 
ARText - Driving Developments with Xtext
ARText - Driving Developments with XtextARText - Driving Developments with Xtext
ARText - Driving Developments with XtextSebastian Benz
 
Xtext, diagrams and ux
Xtext, diagrams and uxXtext, diagrams and ux
Xtext, diagrams and ux
Dr. Jan Köhnlein
 
Language Engineering With Xtext
Language Engineering With XtextLanguage Engineering With Xtext
Language Engineering With Xtext
Sven Efftinge
 

Viewers also liked (20)

Codegeneration Goodies
Codegeneration GoodiesCodegeneration Goodies
Codegeneration Goodies
 
Parsing Expression With Xtext
Parsing Expression With XtextParsing Expression With Xtext
Parsing Expression With Xtext
 
Future of Xtext
Future of XtextFuture of Xtext
Future of Xtext
 
Xtext Best Practices
Xtext Best PracticesXtext Best Practices
Xtext Best Practices
 
Turning Ideas Into Code Faster
Turning Ideas Into Code FasterTurning Ideas Into Code Faster
Turning Ideas Into Code Faster
 
Recipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with XtendRecipes to build Code Generators for Non-Xtext Models with Xtend
Recipes to build Code Generators for Non-Xtext Models with Xtend
 
The Xtext Grammar Language
The Xtext Grammar LanguageThe Xtext Grammar Language
The Xtext Grammar Language
 
EMF - Beyond The Basics
EMF - Beyond The BasicsEMF - Beyond The Basics
EMF - Beyond The Basics
 
EMF Tips n Tricks
EMF Tips n TricksEMF Tips n Tricks
EMF Tips n Tricks
 
Xtend - A Language Made for Java Developers
Xtend - A Language Made for Java DevelopersXtend - A Language Made for Java Developers
Xtend - A Language Made for Java Developers
 
DSLs for Java Developers
DSLs for Java DevelopersDSLs for Java Developers
DSLs for Java Developers
 
Graphical Views For Xtext With FXDiagram
Graphical Views For Xtext With FXDiagramGraphical Views For Xtext With FXDiagram
Graphical Views For Xtext With FXDiagram
 
Graphical Views For Xtext
Graphical Views For XtextGraphical Views For Xtext
Graphical Views For Xtext
 
Jazoon 2010 - Building DSLs with Eclipse
Jazoon 2010 - Building DSLs with EclipseJazoon 2010 - Building DSLs with Eclipse
Jazoon 2010 - Building DSLs with Eclipse
 
Enhancing Xtext for General Purpose Languages
Enhancing Xtext for General Purpose LanguagesEnhancing Xtext for General Purpose Languages
Enhancing Xtext for General Purpose Languages
 
Eclipse DemoCamp in Paris: Language Development with Xtext
Eclipse DemoCamp in Paris: Language Development with XtextEclipse DemoCamp in Paris: Language Development with Xtext
Eclipse DemoCamp in Paris: Language Development with Xtext
 
From Stairway to Heaven onto the Highway to Hell with Xtext
From Stairway to Heaven onto the Highway to Hell with XtextFrom Stairway to Heaven onto the Highway to Hell with Xtext
From Stairway to Heaven onto the Highway to Hell with Xtext
 
ARText - Driving Developments with Xtext
ARText - Driving Developments with XtextARText - Driving Developments with Xtext
ARText - Driving Developments with Xtext
 
Xtext, diagrams and ux
Xtext, diagrams and uxXtext, diagrams and ux
Xtext, diagrams and ux
 
Language Engineering With Xtext
Language Engineering With XtextLanguage Engineering With Xtext
Language Engineering With Xtext
 

Similar to Serializing EMF models with Xtext

Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
Jamund Ferguson
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
Jarrod Overson
 
Swift core
Swift coreSwift core
Swift core
Yusuke Kita
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
Kevin Hazzard
 
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
Eugene Yokota
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-C
Alexis Gallagher
 
Angular2 for Beginners
Angular2 for BeginnersAngular2 for Beginners
Angular2 for Beginners
Oswald Campesato
 
MongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in BavariaMongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB
 
iPhone Development Intro
iPhone Development IntroiPhone Development Intro
iPhone Development Intro
Luis Azevedo
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
Heiko Behrens
 
Awesomeness of JavaScript…almost
Awesomeness of JavaScript…almostAwesomeness of JavaScript…almost
Awesomeness of JavaScript…almost
Quinton Sheppard
 
Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Ramamohan Chokkam
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, SwiftYandex
 
Java Intro
Java IntroJava Intro
Java Introbackdoor
 
Moving to modules
Moving to modulesMoving to modules
Moving to modules
Sean Mize
 

Similar to Serializing EMF models with Xtext (20)

Don't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax TreesDon't Be Afraid of Abstract Syntax Trees
Don't Be Afraid of Abstract Syntax Trees
 
JS everywhere 2011
JS everywhere 2011JS everywhere 2011
JS everywhere 2011
 
JavaScript and the AST
JavaScript and the ASTJavaScript and the AST
JavaScript and the AST
 
Swift core
Swift coreSwift core
Swift core
 
C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607C# 6 and 7 and Futures 20180607
C# 6 and 7 and Futures 20180607
 
Json the-x-in-ajax1588
Json the-x-in-ajax1588Json the-x-in-ajax1588
Json the-x-in-ajax1588
 
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
sbt, history of JSON libraries, microservices, and schema evolution (Tokyo ver)
 
Swift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-CSwift, functional programming, and the future of Objective-C
Swift, functional programming, and the future of Objective-C
 
Gcrc talk
Gcrc talkGcrc talk
Gcrc talk
 
Angular2 for Beginners
Angular2 for BeginnersAngular2 for Beginners
Angular2 for Beginners
 
MongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in BavariaMongoDB Munich 2012: MongoDB for official documents in Bavaria
MongoDB Munich 2012: MongoDB for official documents in Bavaria
 
Es.next
Es.nextEs.next
Es.next
 
Java
JavaJava
Java
 
iPhone Development Intro
iPhone Development IntroiPhone Development Intro
iPhone Development Intro
 
Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009Building DSLs with Xtext - Eclipse Modeling Day 2009
Building DSLs with Xtext - Eclipse Modeling Day 2009
 
Awesomeness of JavaScript…almost
Awesomeness of JavaScript…almostAwesomeness of JavaScript…almost
Awesomeness of JavaScript…almost
 
Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02Jsonsaga 100605143125-phpapp02
Jsonsaga 100605143125-phpapp02
 
Denis Lebedev, Swift
Denis  Lebedev, SwiftDenis  Lebedev, Swift
Denis Lebedev, Swift
 
Java Intro
Java IntroJava Intro
Java Intro
 
Moving to modules
Moving to modulesMoving to modules
Moving to modules
 

Recently uploaded

20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
Matthew Sinclair
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
Ana-Maria Mihalceanu
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
KAMESHS29
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
Quotidiano Piemontese
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
Safe Software
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
Pierluigi Pugliese
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
James Anderson
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
Alpen-Adria-Universität
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
Neo4j
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
SOFTTECHHUB
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
Matthew Sinclair
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Aggregage
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
Uni Systems S.M.S.A.
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
DanBrown980551
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
danishmna97
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Vladimir Iglovikov, Ph.D.
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
Aftab Hussain
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
RinaMondal9
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
Adtran
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
Alan Dix
 

Recently uploaded (20)

20240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 202420240607 QFM018 Elixir Reading List May 2024
20240607 QFM018 Elixir Reading List May 2024
 
Monitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR EventsMonitoring Java Application Security with JDK Tools and JFR Events
Monitoring Java Application Security with JDK Tools and JFR Events
 
RESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for studentsRESUME BUILDER APPLICATION Project for students
RESUME BUILDER APPLICATION Project for students
 
National Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practicesNational Security Agency - NSA mobile device best practices
National Security Agency - NSA mobile device best practices
 
Essentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FMEEssentials of Automations: The Art of Triggers and Actions in FME
Essentials of Automations: The Art of Triggers and Actions in FME
 
By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024By Design, not by Accident - Agile Venture Bolzano 2024
By Design, not by Accident - Agile Venture Bolzano 2024
 
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
GDG Cloud Southlake #33: Boule & Rebala: Effective AppSec in SDLC using Deplo...
 
Video Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the FutureVideo Streaming: Then, Now, and in the Future
Video Streaming: Then, Now, and in the Future
 
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024GraphSummit Singapore | The Art of the  Possible with Graph - Q2 2024
GraphSummit Singapore | The Art of the Possible with Graph - Q2 2024
 
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
Goodbye Windows 11: Make Way for Nitrux Linux 3.5.0!
 
20240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 202420240605 QFM017 Machine Intelligence Reading List May 2024
20240605 QFM017 Machine Intelligence Reading List May 2024
 
Generative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to ProductionGenerative AI Deep Dive: Advancing from Proof of Concept to Production
Generative AI Deep Dive: Advancing from Proof of Concept to Production
 
Microsoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdfMicrosoft - Power Platform_G.Aspiotis.pdf
Microsoft - Power Platform_G.Aspiotis.pdf
 
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
LF Energy Webinar: Electrical Grid Modelling and Simulation Through PowSyBl -...
 
How to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptxHow to Get CNIC Information System with Paksim Ga.pptx
How to Get CNIC Information System with Paksim Ga.pptx
 
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AIEnchancing adoption of Open Source Libraries. A case study on Albumentations.AI
Enchancing adoption of Open Source Libraries. A case study on Albumentations.AI
 
Removing Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software FuzzingRemoving Uninteresting Bytes in Software Fuzzing
Removing Uninteresting Bytes in Software Fuzzing
 
Free Complete Python - A step towards Data Science
Free Complete Python - A step towards Data ScienceFree Complete Python - A step towards Data Science
Free Complete Python - A step towards Data Science
 
Pushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 daysPushing the limits of ePRTC: 100ns holdover for 100 days
Pushing the limits of ePRTC: 100ns holdover for 100 days
 
Epistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI supportEpistemic Interaction - tuning interfaces to provide information for AI support
Epistemic Interaction - tuning interfaces to provide information for AI support
 

Serializing EMF models with Xtext

  • 1. Moritz Eysholdt, itemis AG Serializing EMF models with Xtext Xtextcon 2014! Kiel, Germany
  • 2. Agenda ❖ Parsing vs. Serializing! ❖ Use Cases! ❖ Generating vs. Serializing! ❖ Challenges! ❖ The Contract! ❖ Architecture! ❖ Hooks! ❖ Advice
  • 3. The New and the Old Serializer org.eclipse.xtext.serializer •The New Serializer. This presentation is about it. org.eclipse.xtext.parsetree.reconstr •The Old Serializer. Don’t used it.! •Cryptic Error Messages! •Bad Performance for Large Models! •marked @Deprecated
  • 11. Why Serialize? ❖ object model usually easier to modify than its textual representation! ❖ guaranteed syntactical correctness! ❖ automatic handling of comments! ❖ automatic handling of whitespace …when I have Xtend, THE language for generators
  • 12. When not to Serialize ❖ Avoid serializing models that are broken due to parse errors.! ❖ Template languages are simpler when writing out large text chunks that never change.
  • 13. The hard Contract Parsing a serialized Model must result ! in a model equal to the original. Model original = createModel() String serialized = serialize(original) Model parsed = parse(serialized) assertEqual(original, parsed) …enables textual models as persistence format
  • 14. The soft Contract Serializing a model that has been modified after parsing! should only change the smallest number of characters necessary. …keep diffs small String originalDoc = loadDocument() Model parsed = parse(originalDoc) Model modified = applyModifications(parsed) String newDoc = serialize(modified) int numberOfChars = diff(originalDoc, newDoc).size() 1. Keep textual diffs small.! 2. Strictly comply with the semantic model! 3. Loosely comply with the node model
  • 15. Challenges ❖ unassigned elements! ❖ ambiguous mapping from EStructuralFeatures to Assignments! ❖ ambiguous mapping from EClasses to ParserRules and Actions …because the AST is actually abstract, as in “lack of information”
  • 16. API Frontends #1 package org.eclipse.xtext.resource; ! public class XtextResource extends ResourceImpl { ! (…) ! public void save(Map<?, ?> options) throws IOException {} ! public final void save(OutputStream outputStream, Map<?, ?> options) throws IOException {} }
  • 17. API Frontends #2 package org.eclipse.xtext.serializer; ! @ImplementedBy(Serializer.class) public interface ISerializer { public String serialize(EObject obj); public String serialize(EObject obj, SaveOptions options); public void serialize(EObject obj, Writer writer, SaveOptions options) throws IOException; public ReplaceRegion serializeReplacement(EObject obj, SaveOptions options); } Options:! - format: ! - true: format all! - false: format regions without whitespace information! - validate: don’t use, it’s an old algorithm.
  • 18. Before Serialization Create one State Machine per Context per EClass Root: "optional"? ID children+=(List | Path); ! List returns Child: "list" item+=ID ("," item+=ID)*; ! Path returns Child: "path" seg=ID ({Segment.parent=current} seg=ID)+; Context EClass Root Root List Child Path Segment Path_Segment_2_0 Child Path_Segment_2_0 Segment
  • 19. During Serialization #1 Find right state machines and ! find right path through them Root: "optional"? ID children+=(List | Path); ! List returns Child: "list" item+=ID ("," item+=ID)*; Context EClass Root Root Context EClass List Child optional Foo list a, b, cOutput:
  • 20. Architecture #3 Context EClass Root Root Context EClass List Child Context EClass Root Root Context EClass List Child Semantic! assigned grammar elements Syntactic! unassigned grammar elements optional Foo list a, b, cOutput:
  • 21. Architecture #4: Observer Semantic! Sequencer Syntactic! Sequencer HiddenToken! Sequencer Formatter Writer Events Listens To assigend! * RuleCalls! * Terminals! * DataTypes! * Keywords! * CrossRefs unassigned! * RuleCalls! * Terminals! * DataTypes! * Keywords * whitespace! * comments modifies! whitespace writes to ! stream
  • 22. Output: /*X*/ Foo list a Serializer HiddenTokenSequencerSyntacticSequencerSemanticSequencer createSequence (Root, Root) enter AssignedParserRuleCall (children=List) enter AssignedParserRuleCall (children=List) createSequence (List, Children) accept UnassignedRuleCall (ID) accept AssignedTerminalRuleCall (itemi=ID) accept Keyword ("list") accept AssignedTerminalRuleCall (itemi=ID) leave AssignedParserRuleCall (children=List) leave AssignedParserRuleCall (children=List) Formatter Writer enterAssignedParserRuleCall() acceptWhitespace() acceptWhitespace() acceptComment(/*X*/) acceptUnassignedRuleCall() acceptKeyword() acceptWhitespace() acceptAssignedTerminalRuleCall() acceptWhitespace() enterAssignedParserRuleCall() Root: "optional"? ID children+=(List | Path); List returns Child: "list" item+=ID ("," item+=ID)*;
  • 23. SerializerFragment fragment = serializer.SerializerFragment auto-inject { generateStub = true // generateDebugData = true } •SerializerFragment not required to use serializer!! •Only purpose of SerializerFragment is to generate convenience API! •generateDebugData to generate pretty state machine diagrams (graphviz dot)
  • 24. Hooks #1: ITransientValueService •selectively exclude model-objects and -values from serialization! •transient == NOT serialized! •Default setting from Ecore model: EStructuralFeature.isTransient() public interface ITransientValueService { ! enum ListTransient { NO, SOME, YES } ! enum ValueTransient { NO, PREFERABLY, YES } ! public ListTransient isListTransient(EObject semanticObject, EStructuralFeature feature); ! public boolean isValueInListTransient(EObject semanticObject, int index, EStructuralFeature feature); ! public ValueTransient isValueTransient(EObject semanticObject, EStructuralFeature feature); }
  • 25. Hooks #2: Token Serialization public interface ICrossReferenceSerializer { boolean isValid(EObject context, CrossReference crossref, EObject target, INode node); String serializeCrossRef(EObject context, CrossReference crossref, EObject target, INode node); } public interface IKeywordSerializer { boolean isValid(EObject context, Keyword keyword, Object value); String serializeAssignedKeyword(EObject context, Keyword keyword, Object value, INode node); } public interface IValueSerializer { boolean isValid(EObject context, RuleCall ruleCall, Object value); String serializeAssignedValue(EObject context, RuleCall ruleCall, Object value, INode node); } public interface IEnumLiteralSerializer { boolean isValid(EObject context, RuleCall ruleCall, Object value); String serializeAssignedEnumLiteral(EObject context, RuleCall ruleCall, Object value, INode node); }
  • 26. Hooks #3: SemanticSequencer class SerSipSemanticSequencer extends AbstractSerSipSemanticSequencer { ! @Inject SerSipGrammarAccess grammarAccess; ! /** * Constraint: * (children+=Path | children+=List) */ override protected sequence_Root(EObject context, Root semanticObject) { val feeder = createSequencerFeeder(semanticObject) for (child : semanticObject.children) { if (child.seg != null) { feeder.accept(grammarAccess.rootAccess.childrenPathParserRuleCall_2_0_0, child) } else { feeder.accept(grammarAccess.rootAccess.childrenListParserRuleCall_2_0_1, child) } } feeder.finish() } } Root: "optional"? ID children+=(Path | List); ! List returns Child: "list" item+=ID ("," item+=ID)*; ! Path returns Child: "path" seg=ID ({Segment.parent=current} seg=ID)+;
  • 27. Hooks #4: SyntacticSequencer class SerSipSyntacticSequencer extends AbstractSerSipSyntacticSequencer { ! /** * terminal ID : '^'?('a'..'z'|'A'..'Z'|'_') ('a'..'z'|'A'..'Z'|'_'|'0'..'9')*; */ override getIDToken(EObject semanticObject, RuleCall ruleCall, INode node) { if (node != null) return getTokenText(node); return ""; } ! /** * Syntax: * 'optional'? */ override emit_Root_OptionalKeyword_0_q(EObject semanticObject, ISynNavigable transition, List<INode> nodes) { acceptNodes(transition, nodes); } } Root: "optional"? ID children+=(Path | List);
  • 28. Understanding Ambiguities •A grammar is ambiguous for the serializer if there can be more than one textual syntax for a given model.! ! •A grammar is ambiguous for the parser if there can be more than one model for a given textual syntax1. R1: foo=ID | bar=ID; R2: (“foo” val=ID) | (“bar” val=ID); Does “a” parse to or ?foo=a bar=b Does serialize to “foo b” or “bar b”? val=b parseserialize 1. that is not completely correct. A grammar is ambiguous when there is more than one path to consume a given input. That, however, usually leads to different models.
  • 29. Understanding Ambiguities Root: (foos=Foo | bars=Bar)*; ! Foo: “foo” foo=ID; ! Bar: “bar” bar=ID; (1) . (2) bar b foo a (3) foo a bar b Root foo=a bar=b Does (1) serialize to (2) or (3)?
  • 30. Avoiding Ambiguities Analysis: Grammars can be ambiguous for the serializer.! ! Example: Root: (foos=Foo | bars=Bar)*; ! Foo: “foo” foo=ID; ! Bar: “bar” bar=ID; Root: members+=Member; ! Member: Foo | Bar; ! Foo: “foo” foo=ID; ! Bar: “bar” bar=ID; •Single “member” list to maintain order! •“Foo” and “Bar” extend “Member”! •implement getFoo() and getBar() as filters on getMembers()
  • 31. Avoid Unserializeable Models The Xtext grammar can imply constraints on your model. ! ! Serialization is only possible if the model complies with theses constraints because the grammar does not define syntax for models that don’t comply. Examples: GRAMMAR CONSTRAINT R1: name=ID; name != null R2: (name=ID | title=STING); (name != null) ^ (title != null) R3: items+=ID+; items.size() >= 1 R4: (a+=ID b+=ID)*; a.size() == b.size()
  • 32. Avoid Unserializeable Models Solution:! ! a) Ensure your grammar does not imply constraints. ! b) Ensure your TransientValueService prevents constraint violations.! Implement Xtext Validation to enforce constraints.! ! This will also improve your error messages but may make content assist too chatty. RESTRICTIVE SAFE R1: name=ID; R1: name=ID?; R1: (name=ID | “?”); R2: (name=ID | title=STING); R2: name=ID? title=STING?; R3: items+=ID+; R3: items+=ID*; R4: (a+=ID b+=ID)*; R4: (a+=ID b+=ID)* (“spareA={“ a+=ID+ “}”)? (“spareB={“ b+=ID+ “}”)?;
  • 33. Configure Your Scope Right You can (and need) to configure global scoping for a ResourceSet! XtextLiveScopeResourceSetProviderXtextResourceSetProvider ResourceSet Dirty Editor State Index (default) (what you need) <shadows> <shadows> Dirty Editor State Index <shadows>