(:~ LSPserver type definitions 
@see https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/
@author Andy Bunce
:)
module namespace lspt = 'lsp-typedefs';

(:~ json numbers :)
declare type lspt:num as (xs:integer|xs:double); 

(:~ 
@param line Line position in a document (zero-based).
@param character Character offset on a line in a document (zero-based).
:)
declare record lspt:Position(
	line as lspt:num,
	character as lspt:num
);

(:~ 
@param line Line position in a document (zero-based).
@param character Character offset on a line in a document (zero-based).
:)
declare record lspt:Range(
	start as lspt:Position,
	end as lspt:Position
);

declare type lspt:SymbolKind as xs:integer;
declare type lspt:SymbolTag as xs:string;

declare record lspt:symbol (
 name as xs:string,
 type as xs:string,
 range-name? as lspt:Range,
 range-full? as lspt:Range,
 children? as array(lspt:symbol)
);

declare record lspt:DocumentSymbol(

(: The name of this symbol. Will be displayed in the user interface and
therefore must not be an empty string or a string only consisting of white spaces. :)
	name as xs:string,

(: The kind of this symbol. :)
	kind as lspt:SymbolKind,

(: The range enclosing this symbol not including leading/trailing whitespace
 but everything else like comments. This information is typically used to
 determine if the clients cursor is inside the symbol to reveal it  in the UI. :)
	range as lspt:Range,

(:The range that should be selected and revealed when this symbol is being
 picked, e.g. the name of a function. Must be contained by the `range`. :)
	selectionRange as lspt:Range,
     
(: More detail for this symbol, e.g the signature of a function.:)
	detail? as xs:string,

(: Tags for this document symbol. @since 3.16.0 :)
	tags? as lspt:SymbolTag*,

(: Children of this symbol, e.g. properties of a class. :)
	children? as lspt:DocumentSymbol*
);

(: @see https://code.visualstudio.com/api/references/vscode-api#SymbolKind :)
declare variable $lspt:SymbolKindMap :={
   'File': 0 ,
   'Module': 1 ,
   'Namespace': 2 ,
   'Package': 3 ,
   'Class': 4 ,
   'Method': 5 ,
   'Property': 6 ,
   'Field': 7 ,
   'Constructor': 8 ,
   'Enum': 9 ,
   'Interface': 10 ,
   'Function': 11 ,
   'Variable': 12 ,
   'Constant': 13 ,
   'String': 14 ,
   'Number': 15 ,
   'Boolean': 16 ,
   'Array': 17 ,
   'Object': 18 ,
   'Key': 19 ,
   'Null': 20 ,
   'EnumMember': 21 ,
   'Struct': 22 ,
   'Event': 23 ,
   'Operator': 24 ,
   'TypeParameter': 25 
};

declare variable $lspt:SeverityKind:={
   'error':1,
   'warning':2,
   'info':3,  
   'hint':4 
};

declare record lspt:Diagnostic(
  range as lspt:Range,
  severity as  xs:integer, (: enum('error', 'hint', 'info', 'warning') :)
  message as xs:string,
  code? as xs:string,
  source as xs:string:="xquery"
);
declare type lspt:TraceValue as enum( 'off' , 'messages' , 'verbose');

(: -----------------completions ------------------:)

(:
 The kind of a completion entry. :)

declare variable $lspt:CompletionItemKindMap:= {
	"Text": 1,
	"Method": 2,
	"Function": 3,
	"Constructor": 4,
	"Field": 5,
	"Variable": 6,
	"Class": 7,
	"Interface": 8,
	"Module": 9,
	"Property": 10,
	"Unit": 11,
	"Value": 12,
	"Enum": 13,
	"Keyword": 14,
	"Snippet": 15,
	"Color": 16,
	"File": 17,
	"Reference": 18,
	"Folder": 19,
	"EnumMember": 20,
	"Constant": 21,
	"Struct": 22,
	"Event": 23,
	"Operator": 24,
	"TypeParameter": 25
};

declare type lspt:CompletionItemKind as xs:integer;

(:  1=Completion was triggered by typing an identifier (24x7 code
    complete), manual invocation (e.g Ctrl+Space) or via API.
    2=Completion was triggered by a trigger character specified by
	   the `triggerCharacters` properties of the `CompletionRegistrationOptions`.
	 3=Completion was re-triggered as the current completion list is incomplete.
 :)
declare type lspt:CompletionTriggerKind as xs:integer(: 1 | 2 | 3 :);

(:
export interface CompletionItem {

	/**
	 * The label of this completion item.
	 *
	 * The label property is also by default the text that
	 * is inserted when selecting this completion.
	 *
	 * If label details are provided the label itself should
	 * be an unqualified name of the completion item.
	 */
	label: string;

	/**
	 * Additional details for the label
	 *
	 * @since 3.17.0
	 */
	labelDetails?: CompletionItemLabelDetails;


	/**
	 * The kind of this completion item. Based of the kind
	 * an icon is chosen by the editor. The standardized set
	 * of available values is defined in `CompletionItemKind`.
	 */
	kind?: CompletionItemKind;

	/**
	 * Tags for this completion item.
	 *
	 * @since 3.15.0
	 */
	tags?: CompletionItemTag[];

	/**
	 * A human-readable string with additional information
	 * about this item, like type or symbol information.
	 */
	detail?: string;

	/**
	 * A human-readable string that represents a doc-comment.
	 */
	documentation?: string | MarkupContent;

	/**
	 * Indicates if this item is deprecated.
	 *
	 * @deprecated Use `tags` instead if supported.
	 */
	deprecated?: boolean;

	/**
	 * Select this item when showing.
	 *
	 * *Note* that only one completion item can be selected and that the
	 * tool / client decides which item that is. The rule is that the *first*
	 * item of those that match best is selected.
	 */
	preselect?: boolean;

	/**
	 * A string that should be used when comparing this item
	 * with other items. When omitted the label is used
	 * as the sort text for this item.
	 */
	sortText?: string;

	/**
	 * A string that should be used when filtering a set of
	 * completion items. When omitted the label is used as the
	 * filter text for this item.
	 */
	filterText?: string;

	/**
	 * A string that should be inserted into a document when selecting
	 * this completion. When omitted the label is used as the insert text
	 * for this item.
	 *
	 * The `insertText` is subject to interpretation by the client side.
	 * Some tools might not take the string literally. For example
	 * VS Code when code complete is requested in this example
	 * `con<cursor position>` and a completion item with an `insertText` of
	 * `console` is provided it will only insert `sole`. Therefore it is
	 * recommended to use `textEdit` instead since it avoids additional client
	 * side interpretation.
	 */
	insertText?: string;

	/**
	 * The format of the insert text. The format applies to both the
	 * `insertText` property and the `newText` property of a provided
	 * `textEdit`. If omitted defaults to `InsertTextFormat.PlainText`.
	 *
	 * Please note that the insertTextFormat doesn't apply to
	 * `additionalTextEdits`.
	 */
	insertTextFormat?: InsertTextFormat;

	/**
	 * How whitespace and indentation is handled during completion
	 * item insertion. If not provided the client's default value depends on
	 * the `textDocument.completion.insertTextMode` client capability.
	 *
	 * @since 3.16.0
	 * @since 3.17.0 - support for `textDocument.completion.insertTextMode`
	 */
	insertTextMode?: InsertTextMode;

	/**
	 * An edit which is applied to a document when selecting this completion.
	 * When an edit is provided the value of `insertText` is ignored.
	 *
	 * *Note:* The range of the edit must be a single line range and it must
	 * contain the position at which completion has been requested.
	 *
	 * Most editors support two different operations when accepting a completion
	 * item. One is to insert a completion text and the other is to replace an
	 * existing text with a completion text. Since this can usually not be
	 * predetermined by a server it can report both ranges. Clients need to
	 * signal support for `InsertReplaceEdit`s via the
	 * `textDocument.completion.completionItem.insertReplaceSupport` client
	 * capability property.
	 *
	 * *Note 1:* The text edit's range as well as both ranges from an insert
	 * replace edit must be a [single line] and they must contain the position
	 * at which completion has been requested.
	 * *Note 2:* If an `InsertReplaceEdit` is returned the edit's insert range
	 * must be a prefix of the edit's replace range, that means it must be
	 * contained and starting at the same position.
	 *
	 * @since 3.16.0 additional type `InsertReplaceEdit`
	 */
	textEdit?: TextEdit | InsertReplaceEdit;

	/**
	 * The edit text used if the completion item is part of a CompletionList and
	 * CompletionList defines an item default for the text edit range.
	 *
	 * Clients will only honor this property if they opt into completion list
	 * item defaults using the capability `completionList.itemDefaults`.
	 *
	 * If not provided and a list's default range is provided the label
	 * property is used as a text.
	 *
	 * @since 3.17.0
	 */
	textEditText?: string;

	/**
	 * An optional array of additional text edits that are applied when
	 * selecting this completion. Edits must not overlap (including the same
	 * insert position) with the main edit nor with themselves.
	 *
	 * Additional text edits should be used to change text unrelated to the
	 * current cursor position (for example adding an import statement at the
	 * top of the file if the completion item will insert an unqualified type).
	 */
	additionalTextEdits?: TextEdit[];

	/**
	 * An optional set of characters that when pressed while this completion is
	 * active will accept it first and then type that character. *Note* that all
	 * commit characters should have `length=1` and that superfluous characters
	 * will be ignored.
	 */
	commitCharacters?: string[];

	/**
	 * An optional command that is executed *after* inserting this completion.
	 * *Note* that additional modifications to the current document should be
	 * described with the additionalTextEdits-property.
	 */
	command?: Command;

	/**
	 * A data entry field that is preserved on a completion item between
	 * a completion and a completion resolve request.
	 */
	data?: LSPAny;
:)
declare record lspt:CompletionItem(
   label as xs:string,
   kind? as  lspt:CompletionItemKind,
   tags?  as xs:string* :=(),
   detail? as xs:string,
   documentation? as (xs:string|lspt:MarkupContent)
);


declare type lspt:MarkupKind as enum('plaintext' , 'markdown');
(: A `MarkupContent` literal represents a string value which content is
 * interpreted base on its kind flag.
 :)
declare record lspt:MarkupContent(
	kind as lspt:MarkupKind,
	value as xs:string
);