You are an expert in writing code in many different languages. Your goal is to perform code completion for the following code, keeping in mind the rest of the code and the file meta data.
    Metadata details:
    filename: hover.rs
    path of file: ./repos/wing/libs/wingc/src/lsp
    
    the code of the file until where you have to start completion: use crate::docs::Documented;
use crate::lsp::sync::PROJECT_DATA;
use crate::type_check::symbol_env::LookupResult;
use crate::visit::Visit;
use crate::wasm_util::extern_json_fn;
use lsp_types::{Hover, HoverContents, MarkupContent, MarkupKind};

use super::symbol_locator::{SymbolLocator, SymbolLocatorResult};
use super::sync::{check_utf8, WING_TYPES};

#[no_mangle]
pub unsafe extern "C" fn wingc_on_hover(ptr: u32, len: u32) -> u64 {
	extern_json_fn(ptr, len, on_hover)
}
pub fn on_hover(params: lsp_types::HoverParams) -> Option<Hover> {
	WING_TYPES.with(|types| {
		let types = types.borrow_mut();
		PROJECT_DATA.with(|project_data| {
			let project_data = project_data.borrow();
			let uri = params.text_document_position_params.text_document.uri.clone();
			let file = check_utf8(uri.to_file_path().expect("LSP only works on real filesystems"));
			let root_scope = &project_data.asts.get(&file).unwrap();

			let mut symbol_finder = SymbolLocat
    
pub fn on_hover(params: lsp_types::HoverParams) -> Option<Hover> {
	WING_TYPES.with(|types| {
		let types = types.borrow_mut();
		PROJECT_DATA.with(|project_data| {
			let project_data = project_data.borrow();
			let uri = params.text_document_position_params.text_document.uri.clone();
			let file = check_utf8(uri.to_file_path().expect("LSP only works on real filesystems"));
			let root_scope = &project_data.asts.get(&file).unwrap();

			let mut symbol_finder = SymbolLocator::new(&types, params.text_document_position_params.position.into());
			symbol_finder.visit_scope(root_scope);

			if let Some(lookup) = symbol_finder.lookup_located_symbol() {
				if let LookupResult::Found(symbol_info, ..) = &lookup {
					let docs = symbol_info.render_docs();
					let span = symbol_finder.located_span()?;
					return Some(Hover {
						contents: HoverContents::Markup(MarkupContent {
							kind: MarkupKind::Markdown,
							value: docs,
						}),
						range: Some(span.into()),
					});
				}
			} else {
				if let SymbolLocatorResult::LooseField { field_type, field, .. } = &symbol_finder.result {
					let span = symbol_finder.located_span().unwrap();
					let value = format!("```wing\n{}: {field_type}\n```", field.name);

					return Some(Hover {
						contents: HoverContents::Markup(MarkupContent {
							kind: MarkupKind::Markdown,
							value,
						}),
						range: Some(span.into()),
					});
				}
			}

			None
		})
	})
}