Skip to content

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:

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: SyncHook
  • validate: AsyncParallelHook
  • onValidateEnd: SyncWaterfallHook
  • complete: AsyncParallelHook
  • hover: SyncBailHook
  • definition: SyncBailHook

Example:

lsp.hooks.validate.tap("MyPlugin", (docContext, validationContext) => {
// Add custom validation logic
});

These are hooks that can be used to extend the LSP functionality.

SyncWaterfallHook

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:

  1. Diagnostic[]: Array of diagnostics collected during validation
  2. Object with:
    • documentContext: A DocumentContext object with:
      • log (Logger): Logger for messages
      • document (TextDocument): The underlying text document
      • PlayerContent (PlayerContent): The parsed Player Content AST
    • addFixableViolation (function): Callback to associate a fix with a diagnostic
      • Parameters: (diag: Diagnostic, violation: Violation) => void

Returns: Diagnostic[]

When Called: At the end of validateTextDocument() after all validation and AST walking is complete


AsyncParallelHook

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:

  1. DocumentContext: A DocumentContext object with:
    • log (Logger): Logger for messages
    • document (TextDocument): The underlying text document
    • PlayerContent (PlayerContent): The parsed Player Content AST
  2. ValidationContext: A ValidationContext object with:
    • addViolation (function): Add a validation violation
      • Parameters: (violation: Violation) => void
    • useASTVisitor (function): Register an AST visitor to walk the syntax tree
      • Parameters: (visitor: ASTVisitor) => void
    • addDiagnostic (function): Add a diagnostic directly
      • Parameters: (diagnostic: Diagnostic) => void

Returns: void

When Called: During validateTextDocument() after syntax errors are collected

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.

AsyncParallelHook

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:

  1. EnhancedDocumentContextWithPosition: An EnhancedDocumentContextWithPosition object with:
    • log (Logger): Logger for messages
    • document (TextDocument): The underlying text document
    • PlayerContent (PlayerContent): The parsed Player Content AST
    • position (Position): The cursor position
    • node (ASTNode): The AST node at the cursor position
    • XLR (XLRContext, optional): XLR type information for the node
  2. CompletionContext: A CompletionContext object with:
    • addCompletionItem (function): Add a completion suggestion
      • Parameters: (item: CompletionItem) => void

Returns: void

When Called: During getCompletionsAtPosition() when the user requests completions


SyncBailHook

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:

  1. EnhancedDocumentContextWithPosition: An EnhancedDocumentContextWithPosition object with:
    • log (Logger): Logger for messages
    • document (TextDocument): The underlying text document
    • PlayerContent (PlayerContent): The parsed Player Content AST
    • position (Position): The cursor position
    • node (ASTNode): The AST node at the cursor position
    • XLR (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:

  1. EnhancedDocumentContextWithPosition: An EnhancedDocumentContextWithPosition object with:
    • log (Logger): Logger for messages
    • document (TextDocument): The underlying text document
    • PlayerContent (PlayerContent): The parsed Player Content AST
    • position (Position): The cursor position
    • node (ASTNode): The AST node at the cursor position
    • XLR (XLRContext, optional): XLR type information for the node

Returns: Hover | undefined

When Called: During getHoverInfoAtPosition() when the user hovers over code


SyncHook

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:

  1. DocumentContext: A DocumentContext object with:
    • log (Logger): Logger for messages
    • document (TextDocument): The underlying text document
    • PlayerContent (PlayerContent): The parsed Player Content AST

Returns: void

When Called: After parsing a document in updateSource()

These are functions that plugin authors may use to extend and configure the language service.

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): void

Parameters:

  • plugin: A PlayerLanguageServicePlugin object with:
    • name (string): The name of the plugin
    • apply(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
});
}
});

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>): void

Parameters:

  • transforms: An object mapping transform names to TransformFunctions. For more details on TransformFunctions, see the XLR documentation.

Example:

lsp.addXLRTransforms({
"exampleTransform1": exampleTransform1Fn,
"exampleTransform2": exampleTransform2Fn,
});

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.json from the provided paths. E.g. if you provide ./example as 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.


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 plugin
    • capabilities (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 service
await lsp.setAssetTypesFromModule([Manifest]);

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.

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: A TextDocument object representing the text document to format
  • options: A FormattingOptions object with:
    • tabSize (number): Size of a tab in spaces
    • insertSpaces (boolean): Prefer spaces over tabs
  • range: Optional Range object to format (if not provided, formats entire document)

Returns: Array of text edits to apply, or undefined


Returns available code actions (quick fixes) for diagnostics in a document.

Signature:

getCodeActionsInRange(
document: TextDocument,
context: CodeActionContext
): Promise<CodeAction[]>

Parameters:

  • document: A TextDocument object representing the text document
  • context: A CodeActionContext object with:
    • diagnostics (Diagnostic[]): Array of diagnostics to provide fixes for

Returns: Array of available code actions


Returns code completion suggestions at a specific position.

Signature:

getCompletionsAtPosition(
document: TextDocument,
position: Position
): Promise<CompletionList>

Parameters:

  • document: A TextDocument object representing the text document
  • position: A Position object with:
    • line (number): Line position (zero-based)
    • character (number): Character offset on a line (zero-based)

Returns: A completion list with suggestions


Returns the definition location for a symbol at a specific position.

Signature:

getDefinitionAtPosition(
document: TextDocument,
position: Position
): Promise<Location | undefined | null>

Parameters:

  • document: A TextDocument object representing the text document
  • position: A Position object 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


Returns hover information at a specific position.

Signature:

getHoverInfoAtPosition(
document: TextDocument,
position: Position
): Promise<Hover | undefined | null>

Parameters:

  • document: A TextDocument object representing the text document
  • position: A Position object 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


Cleans up cached data for a closed document.

Signature:

onClose(document: TextDocument): void

Parameters:

  • document: A TextDocument object representing the text document being closed

Resolves additional information for a completion item. Currently, this method just returns the item unchanged.

Signature:

resolveCompletionItem(
completionItem: CompletionItem
): Promise<CompletionItem>

Parameters:

  • completionItem: A CompletionItem object to resolve

Returns: The resolved completion item (currently unchanged)


Validates a document and returns diagnostics (errors, warnings, etc.).

Signature:

validateTextDocument(
document: TextDocument
): Promise<Array<Diagnostic> | undefined>

Parameters:

  • document: A TextDocument object representing the text document to validate

Returns: Array of diagnostics, or undefined