- Define an interface for the stub, derived from the StubElement interface (example)
- Provide an implementation for the interface (example)
- Make sure that the interface for the PSI element extends StubBasedPsiElement parameterized by the type of the stub interface (example)
- Make sure that the implementation class for the PSI element extends StubBasedPsiElementBase parameterized by the type of the stub interface (example). Provide both a constructor that accepts an ASTNode and a constructor which accepts a stub.
- Create a class which implements IStubElementType and is parameterized with the stub interface and the actual PSI element interface (example). Implement the createPsi() and createStub() methods for creating PSI from a stub and vice versa. Implement the serialize() and deserialize() methods for storing the data in a binary stream.
- Use the class implementing IStubElementType as the element type constant when parsing (example)
- Make sure that all methods in the PSI element interface access the stub data rather than the PSI tree when appropriate (example: Property.getKey() implementation|https://github.com/JetBrains/intellij-community/blob/master/plugins/properties/src/com/intellij/lang/properties/psi/impl/PropertyImpl.java#L97)
The following steps need to be performed only once for each language that supports stubs: