Player Language Service (LSP)
The PlayerLanguageService is the foundation for interacting with Player Content. It conforms to the Language Server Protocol standards, and the docs refer to this PlayerLanguageService as “The LSP”. The LSP parses JSON to a manipulable Abstract Syntax Tree (AST). It also provides features like validating that Player Content adheres to both Player semantics and the specifics of the Player integration.
As a user of Player, you will typically not create your own LSP, rather you’ll use one that already integrated into a tool. For example, the Player CLI instantiates an LSP for use with content based operations.
Plugins that manipulate the LSP can be added to the Player CLI. How to create and use CLI plugins is described in the CLI Plugins section.
You may interact with an LSP in the following ways:
- Use its public properties
- Tap into its hooks
- Call its functions
Public Properties
Section titled “Public Properties”XLRService
Section titled “XLRService”The XLR (Cross Language Representation) service that handles type information and transformations for XLRs that are used by the LSP. For more information on XLR, see the XLR documentation.
Access the XLR service to add custom transforms or work with type definitions.
Type: XLRService (readonly)
Example:
lsp.XLRService.XLRSDK.hasType('InputAsset');An object containing all the tapable hooks that plugins can use to extend LSP functionality. See the Hooks to Extend LSP Functionality or LSP-Standard hooks section for detailed information about each hook.
Type: Object with 6 hooks (readonly)
onDocumentUpdate: SyncHookvalidate: AsyncParallelHookonValidateEnd: SyncWaterfallHookcomplete: AsyncParallelHookhover: SyncBailHookdefinition: SyncBailHook
Example:
lsp.hooks.validate.tap("MyPlugin", (docContext, validationContext) => { // Add custom validation logic});Hooks to Extend LSP Functionality
Section titled “Hooks to Extend LSP Functionality”These are hooks that can be used to extend the LSP functionality.
onValidateEnd
Section titled “onValidateEnd”Called synchronously after validation completes. Allows plugins to modify, filter, or add to the final list of diagnostics. Each tap receives the result of the previous tap (waterfall pattern).
Parameters:
Diagnostic[]: Array of diagnostics collected during validation- Object with:
documentContext: ADocumentContextobject with:log(Logger): Logger for messagesdocument(TextDocument): The underlying text documentPlayerContent(PlayerContent): The parsed Player Content AST
addFixableViolation(function): Callback to associate a fix with a diagnostic- Parameters:
(diag: Diagnostic, violation: Violation) => void
- Parameters:
Returns: Diagnostic[]
When Called: At the end of validateTextDocument() after all validation and AST walking is complete
validate
Section titled “validate”Called asynchronously in parallel to validate the document. Plugins can add validation rules, register AST visitors to walk the syntax tree, and report violations or diagnostics. All taps run in parallel.
Parameters:
DocumentContext: ADocumentContextobject with:log(Logger): Logger for messagesdocument(TextDocument): The underlying text documentPlayerContent(PlayerContent): The parsed Player Content AST
ValidationContext: AValidationContextobject with:addViolation(function): Add a validation violation- Parameters:
(violation: Violation) => void
- Parameters:
useASTVisitor(function): Register an AST visitor to walk the syntax tree- Parameters:
(visitor: ASTVisitor) => void
- Parameters:
addDiagnostic(function): Add a diagnostic directly- Parameters:
(diagnostic: Diagnostic) => void
- Parameters:
Returns: void
When Called: During validateTextDocument() after syntax errors are collected
LSP-Standard Hooks
Section titled “LSP-Standard Hooks”These are functions that are part of the LSP standard. They provide useful features that may be leveraged by the Player CLI, or that could be used in an IDE setting (like autocomplete, find definition, etc.), but are not typically relevant for CLI plugin authors.
complete
Section titled “complete”Called asynchronously in parallel to provide code completion suggestions at a specific position. Plugins can analyze the context and add relevant completion items. All taps run in parallel.
Parameters:
EnhancedDocumentContextWithPosition: AnEnhancedDocumentContextWithPositionobject with:log(Logger): Logger for messagesdocument(TextDocument): The underlying text documentPlayerContent(PlayerContent): The parsed Player Content ASTposition(Position): The cursor positionnode(ASTNode): The AST node at the cursor positionXLR(XLRContext, optional): XLR type information for the node
CompletionContext: ACompletionContextobject with:addCompletionItem(function): Add a completion suggestion- Parameters:
(item: CompletionItem) => void
- Parameters:
Returns: void
When Called: During getCompletionsAtPosition() when the user requests completions
definition
Section titled “definition”Called synchronously to provide “go to definition” functionality. The first tap that returns a non-undefined value will stop execution (bail pattern), and that location will be used as the definition target.
Parameters:
EnhancedDocumentContextWithPosition: AnEnhancedDocumentContextWithPositionobject with:log(Logger): Logger for messagesdocument(TextDocument): The underlying text documentPlayerContent(PlayerContent): The parsed Player Content ASTposition(Position): The cursor positionnode(ASTNode): The AST node at the cursor positionXLR(XLRContext, optional): XLR type information for the node
Returns: Location | undefined
When Called: During getDefinitionAtPosition() when the user requests to go to a definition
SyncBailHook
Called synchronously to provide hover information at a specific position. The first tap that returns a non-undefined value will stop execution (bail pattern), and that value will be used as the hover result.
Parameters:
EnhancedDocumentContextWithPosition: AnEnhancedDocumentContextWithPositionobject with:log(Logger): Logger for messagesdocument(TextDocument): The underlying text documentPlayerContent(PlayerContent): The parsed Player Content ASTposition(Position): The cursor positionnode(ASTNode): The AST node at the cursor positionXLR(XLRContext, optional): XLR type information for the node
Returns: Hover | undefined
When Called: During getHoverInfoAtPosition() when the user hovers over code
onDocumentUpdate
Section titled “onDocumentUpdate”Called synchronously when a document is updated or parsed. Use this hook to react to document changes and perform any necessary setup or state updates.
Parameters:
DocumentContext: ADocumentContextobject with:log(Logger): Logger for messagesdocument(TextDocument): The underlying text documentPlayerContent(PlayerContent): The parsed Player Content AST
Returns: void
When Called: After parsing a document in updateSource()
Functions to Configure the LSP
Section titled “Functions to Configure the LSP”These are functions that plugin authors may use to extend and configure the language service.
addLSPPlugin
Section titled “addLSPPlugin”Multiple taps of the LSP hooks and complex logic can be bundled together into a single PlayerLanguageServicePlugin. That plugin can then be added to the LSP using this function.
Signature:
addLSPPlugin(plugin: PlayerLanguageServicePlugin): voidParameters:
plugin: APlayerLanguageServicePluginobject with:name(string): The name of the pluginapply(languageService: PlayerLanguageService)(function): Function that receives the language service instance and applies the plugin’s functionality
Example:
lsp.addLSPPlugin({ name: "MyCustomPlugin", apply(languageService: PlayerLanguageService) { languageService.hooks.validate.tap("MyCustomPlugin", (doc, ctx) => { // Custom validation logic }); }});addXLRTransforms
Section titled “addXLRTransforms”Adds custom XLR transform functions to the XLR service. For more information on XLR transforms, see the XLR documentation.
Signature:
addXLRTransforms(transforms: Record<string, TransformFunction>): voidParameters:
transforms: An object mapping transform names toTransformFunctions. For more details onTransformFunctions, see the XLR documentation.
Example:
lsp.addXLRTransforms({ "exampleTransform1": exampleTransform1Fn, "exampleTransform2": exampleTransform2Fn,});setAssetTypes
Section titled “setAssetTypes”Loads type definitions from file paths on disk. These types define the complete set of assets and data types available for your Player project.
This function will:
- Load
/xlr/manifest.jsonfrom the provided paths. E.g. if you provide./exampleas the path, it will load./example/xlr/manifest.json. - If the path does NOT have
"types"in the name, some default filters and transforms will be applied. They are defined here. This special handling should be used when you want to load/modify the definition of the base Player types. - If the path DOES have
"types"in the name, these filters and transforms will NOT be applied.
For information on how to generated the manifest.json, see the XLR documentation.
Signature:
setAssetTypes(typeFiles: Array<string>): Promise<void>Parameters:
typeFiles: Path to the directory to load. This can be a local path or the path to a package.
Example:
await lsp.setAssetTypes([ "../types", // A local path path.join(require.resolve('@player-ui/types'), '..', '..'), // A package path]);PlayerUI provides an excellent example of what a definition file looks like here.
setAssetTypesFromModule
Section titled “setAssetTypesFromModule”Loads type definitions from TypeScript manifests into the language service. This method processes each manifest and loads its XLR definitions into the XLRSDK.
If the manifest does NOT have a “Types” capability, some default filters and transforms will be applied. They are defined here. This special handling should be used when you want to load/modify the definition of the base Player types.
If the manifest DOES have a “Types” capability, no filters or transforms will be applied.
For information on how to generated the TSManifest, see the XLR documentation.
Signature:
setAssetTypesFromModule(manifest: Array<TSManifest>): Promise<void>Parameters:
manifest(Array<TSManifest>): Array of TypeScript manifest objects, where each TSManifest contains:pluginName(string): Name of the plugincapabilities(string: Array<NamedType>): Index of capabilities provided by the plugin to the name of the XLR for the capabilities- Each key is a capability name (string)
- Each value is an array of NamedType objects
Returns: Promise<void>
Example:
import type { TSManifest } from "@player-tools/xlr";import Manifest from "@player-ui/types/xlr";
// Load the manifest into the language serviceawait lsp.setAssetTypesFromModule([Manifest]);LSP-Standard Functions
Section titled “LSP-Standard Functions”These are functions that are part of the LSP standard. They provide useful features that are leveraged by the Player CLI, or that can be used for IDE tooling (not yet used by the Player), but are not typically relevant for CLI plugin authors.
formatTextDocument
Section titled “formatTextDocument”Formats a text document (or a range within it) according to formatting options.
Signature:
formatTextDocument( document: TextDocument, options: FormattingOptions, range?: Range): Promise<Array<TextEdit> | undefined>Parameters:
document: ATextDocumentobject representing the text document to formatoptions: AFormattingOptionsobject with:tabSize(number): Size of a tab in spacesinsertSpaces(boolean): Prefer spaces over tabs
range: OptionalRangeobject to format (if not provided, formats entire document)
Returns: Array of text edits to apply, or undefined
getCodeActionsInRange
Section titled “getCodeActionsInRange”Returns available code actions (quick fixes) for diagnostics in a document.
Signature:
getCodeActionsInRange( document: TextDocument, context: CodeActionContext): Promise<CodeAction[]>Parameters:
document: ATextDocumentobject representing the text documentcontext: ACodeActionContextobject with:diagnostics(Diagnostic[]): Array of diagnostics to provide fixes for
Returns: Array of available code actions
getCompletionsAtPosition
Section titled “getCompletionsAtPosition”Returns code completion suggestions at a specific position.
Signature:
getCompletionsAtPosition( document: TextDocument, position: Position): Promise<CompletionList>Parameters:
document: ATextDocumentobject representing the text documentposition: APositionobject with:line(number): Line position (zero-based)character(number): Character offset on a line (zero-based)
Returns: A completion list with suggestions
getDefinitionAtPosition
Section titled “getDefinitionAtPosition”Returns the definition location for a symbol at a specific position.
Signature:
getDefinitionAtPosition( document: TextDocument, position: Position): Promise<Location | undefined | null>Parameters:
document: ATextDocumentobject representing the text documentposition: APositionobject with:line(number): Line position (zero-based)character(number): Character offset on a line (zero-based)
Returns: The location of the definition, or undefined/null if not found
getHoverInfoAtPosition
Section titled “getHoverInfoAtPosition”Returns hover information at a specific position.
Signature:
getHoverInfoAtPosition( document: TextDocument, position: Position): Promise<Hover | undefined | null>Parameters:
document: ATextDocumentobject representing the text documentposition: APositionobject with:line(number): Line position (zero-based)character(number): Character offset on a line (zero-based)
Returns: Hover information, or undefined/null if none available
onClose
Section titled “onClose”Cleans up cached data for a closed document.
Signature:
onClose(document: TextDocument): voidParameters:
document: ATextDocumentobject representing the text document being closed
resolveCompletionItem
Section titled “resolveCompletionItem”Resolves additional information for a completion item. Currently, this method just returns the item unchanged.
Signature:
resolveCompletionItem( completionItem: CompletionItem): Promise<CompletionItem>Parameters:
completionItem: ACompletionItemobject to resolve
Returns: The resolved completion item (currently unchanged)
validateTextDocument
Section titled “validateTextDocument”Validates a document and returns diagnostics (errors, warnings, etc.).
Signature:
validateTextDocument( document: TextDocument): Promise<Array<Diagnostic> | undefined>Parameters:
document: ATextDocumentobject representing the text document to validate
Returns: Array of diagnostics, or undefined