Skip to main content

nwnrs_nwscript/
langspec.rs

1use std::{collections::HashMap, error::Error, fmt};
2
3use serde::{Deserialize, Serialize};
4
5use crate::{
6    CompilerErrorCode, Keyword, LexerError, ScriptResolver, SourceError, SourceFile,
7    SourceLoadOptions, SourceMap, Span, Token, TokenKind,
8    int_literal::{parse_wrapping_decimal_i32, parse_wrapping_prefixed_i32},
9    lex_source, load_source_bundle,
10};
11
12/// Default logical script name for the builtin `NWScript` language definition.
13pub const DEFAULT_LANGSPEC_SCRIPT_NAME: &str = "nwscript";
14
15/// One builtin `NWScript` type defined by `nwscript.nss`.
16#[derive(#[automatically_derived]
impl ::core::fmt::Debug for BuiltinType {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BuiltinType::Int => ::core::fmt::Formatter::write_str(f, "Int"),
            BuiltinType::Float =>
                ::core::fmt::Formatter::write_str(f, "Float"),
            BuiltinType::String =>
                ::core::fmt::Formatter::write_str(f, "String"),
            BuiltinType::Object =>
                ::core::fmt::Formatter::write_str(f, "Object"),
            BuiltinType::Void => ::core::fmt::Formatter::write_str(f, "Void"),
            BuiltinType::Action =>
                ::core::fmt::Formatter::write_str(f, "Action"),
            BuiltinType::Vector =>
                ::core::fmt::Formatter::write_str(f, "Vector"),
            BuiltinType::EngineStructure(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "EngineStructure", &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for BuiltinType {
    #[inline]
    fn clone(&self) -> BuiltinType {
        match self {
            BuiltinType::Int => BuiltinType::Int,
            BuiltinType::Float => BuiltinType::Float,
            BuiltinType::String => BuiltinType::String,
            BuiltinType::Object => BuiltinType::Object,
            BuiltinType::Void => BuiltinType::Void,
            BuiltinType::Action => BuiltinType::Action,
            BuiltinType::Vector => BuiltinType::Vector,
            BuiltinType::EngineStructure(__self_0) =>
                BuiltinType::EngineStructure(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BuiltinType {
    #[inline]
    fn eq(&self, other: &BuiltinType) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (BuiltinType::EngineStructure(__self_0),
                    BuiltinType::EngineStructure(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for BuiltinType {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    BuiltinType::Int =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 0u32, "Int"),
                    BuiltinType::Float =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 1u32, "Float"),
                    BuiltinType::String =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 2u32, "String"),
                    BuiltinType::Object =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 3u32, "Object"),
                    BuiltinType::Void =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 4u32, "Void"),
                    BuiltinType::Action =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 5u32, "Action"),
                    BuiltinType::Vector =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinType", 6u32, "Vector"),
                    BuiltinType::EngineStructure(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinType", 7u32, "EngineStructure", __field0),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for BuiltinType {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __field5,
                    __field6,
                    __field7,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            5u64 => _serde::__private228::Ok(__Field::__field5),
                            6u64 => _serde::__private228::Ok(__Field::__field6),
                            7u64 => _serde::__private228::Ok(__Field::__field7),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 8")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Int" => _serde::__private228::Ok(__Field::__field0),
                            "Float" => _serde::__private228::Ok(__Field::__field1),
                            "String" => _serde::__private228::Ok(__Field::__field2),
                            "Object" => _serde::__private228::Ok(__Field::__field3),
                            "Void" => _serde::__private228::Ok(__Field::__field4),
                            "Action" => _serde::__private228::Ok(__Field::__field5),
                            "Vector" => _serde::__private228::Ok(__Field::__field6),
                            "EngineStructure" =>
                                _serde::__private228::Ok(__Field::__field7),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Int" => _serde::__private228::Ok(__Field::__field0),
                            b"Float" => _serde::__private228::Ok(__Field::__field1),
                            b"String" => _serde::__private228::Ok(__Field::__field2),
                            b"Object" => _serde::__private228::Ok(__Field::__field3),
                            b"Void" => _serde::__private228::Ok(__Field::__field4),
                            b"Action" => _serde::__private228::Ok(__Field::__field5),
                            b"Vector" => _serde::__private228::Ok(__Field::__field6),
                            b"EngineStructure" =>
                                _serde::__private228::Ok(__Field::__field7),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<BuiltinType>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = BuiltinType;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum BuiltinType")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::Int)
                            }
                            (__Field::__field1, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::Float)
                            }
                            (__Field::__field2, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::String)
                            }
                            (__Field::__field3, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::Object)
                            }
                            (__Field::__field4, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::Void)
                            }
                            (__Field::__field5, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::Action)
                            }
                            (__Field::__field6, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinType::Vector)
                            }
                            (__Field::__field7, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<String>(__variant),
                                    BuiltinType::EngineStructure),
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Int", "Float", "String", "Object", "Void", "Action",
                                "Vector", "EngineStructure"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "BuiltinType", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<BuiltinType>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
17pub enum BuiltinType {
18    /// `int`
19    Int,
20    /// `float`
21    Float,
22    /// `string`
23    String,
24    /// `object`
25    Object,
26    /// `void`
27    Void,
28    /// `action`
29    Action,
30    /// `vector`
31    Vector,
32    /// One engine-defined structure such as `effect` or `json`.
33    EngineStructure(String),
34}
35
36/// One literal builtin value extracted from the language spec.
37#[derive(#[automatically_derived]
impl ::core::fmt::Debug for BuiltinValue {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            BuiltinValue::Int(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Int",
                    &__self_0),
            BuiltinValue::Float(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Float",
                    &__self_0),
            BuiltinValue::String(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "String",
                    &__self_0),
            BuiltinValue::ObjectId(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f,
                    "ObjectId", &__self_0),
            BuiltinValue::ObjectSelf =>
                ::core::fmt::Formatter::write_str(f, "ObjectSelf"),
            BuiltinValue::ObjectInvalid =>
                ::core::fmt::Formatter::write_str(f, "ObjectInvalid"),
            BuiltinValue::LocationInvalid =>
                ::core::fmt::Formatter::write_str(f, "LocationInvalid"),
            BuiltinValue::Json(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Json",
                    &__self_0),
            BuiltinValue::Vector(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Vector",
                    &__self_0),
            BuiltinValue::Raw(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Raw",
                    &__self_0),
        }
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for BuiltinValue {
    #[inline]
    fn clone(&self) -> BuiltinValue {
        match self {
            BuiltinValue::Int(__self_0) =>
                BuiltinValue::Int(::core::clone::Clone::clone(__self_0)),
            BuiltinValue::Float(__self_0) =>
                BuiltinValue::Float(::core::clone::Clone::clone(__self_0)),
            BuiltinValue::String(__self_0) =>
                BuiltinValue::String(::core::clone::Clone::clone(__self_0)),
            BuiltinValue::ObjectId(__self_0) =>
                BuiltinValue::ObjectId(::core::clone::Clone::clone(__self_0)),
            BuiltinValue::ObjectSelf => BuiltinValue::ObjectSelf,
            BuiltinValue::ObjectInvalid => BuiltinValue::ObjectInvalid,
            BuiltinValue::LocationInvalid => BuiltinValue::LocationInvalid,
            BuiltinValue::Json(__self_0) =>
                BuiltinValue::Json(::core::clone::Clone::clone(__self_0)),
            BuiltinValue::Vector(__self_0) =>
                BuiltinValue::Vector(::core::clone::Clone::clone(__self_0)),
            BuiltinValue::Raw(__self_0) =>
                BuiltinValue::Raw(::core::clone::Clone::clone(__self_0)),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BuiltinValue {
    #[inline]
    fn eq(&self, other: &BuiltinValue) -> bool {
        let __self_discr = ::core::intrinsics::discriminant_value(self);
        let __arg1_discr = ::core::intrinsics::discriminant_value(other);
        __self_discr == __arg1_discr &&
            match (self, other) {
                (BuiltinValue::Int(__self_0), BuiltinValue::Int(__arg1_0)) =>
                    __self_0 == __arg1_0,
                (BuiltinValue::Float(__self_0), BuiltinValue::Float(__arg1_0))
                    => __self_0 == __arg1_0,
                (BuiltinValue::String(__self_0),
                    BuiltinValue::String(__arg1_0)) => __self_0 == __arg1_0,
                (BuiltinValue::ObjectId(__self_0),
                    BuiltinValue::ObjectId(__arg1_0)) => __self_0 == __arg1_0,
                (BuiltinValue::Json(__self_0), BuiltinValue::Json(__arg1_0))
                    => __self_0 == __arg1_0,
                (BuiltinValue::Vector(__self_0),
                    BuiltinValue::Vector(__arg1_0)) => __self_0 == __arg1_0,
                (BuiltinValue::Raw(__self_0), BuiltinValue::Raw(__arg1_0)) =>
                    __self_0 == __arg1_0,
                _ => true,
            }
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for BuiltinValue {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                match *self {
                    BuiltinValue::Int(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 0u32, "Int", __field0),
                    BuiltinValue::Float(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 1u32, "Float", __field0),
                    BuiltinValue::String(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 2u32, "String", __field0),
                    BuiltinValue::ObjectId(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 3u32, "ObjectId", __field0),
                    BuiltinValue::ObjectSelf =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinValue", 4u32, "ObjectSelf"),
                    BuiltinValue::ObjectInvalid =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinValue", 5u32, "ObjectInvalid"),
                    BuiltinValue::LocationInvalid =>
                        _serde::Serializer::serialize_unit_variant(__serializer,
                            "BuiltinValue", 6u32, "LocationInvalid"),
                    BuiltinValue::Json(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 7u32, "Json", __field0),
                    BuiltinValue::Vector(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 8u32, "Vector", __field0),
                    BuiltinValue::Raw(ref __field0) =>
                        _serde::Serializer::serialize_newtype_variant(__serializer,
                            "BuiltinValue", 9u32, "Raw", __field0),
                }
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for BuiltinValue {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __field4,
                    __field5,
                    __field6,
                    __field7,
                    __field8,
                    __field9,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "variant identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            4u64 => _serde::__private228::Ok(__Field::__field4),
                            5u64 => _serde::__private228::Ok(__Field::__field5),
                            6u64 => _serde::__private228::Ok(__Field::__field6),
                            7u64 => _serde::__private228::Ok(__Field::__field7),
                            8u64 => _serde::__private228::Ok(__Field::__field8),
                            9u64 => _serde::__private228::Ok(__Field::__field9),
                            _ =>
                                _serde::__private228::Err(_serde::de::Error::invalid_value(_serde::de::Unexpected::Unsigned(__value),
                                        &"variant index 0 <= i < 10")),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "Int" => _serde::__private228::Ok(__Field::__field0),
                            "Float" => _serde::__private228::Ok(__Field::__field1),
                            "String" => _serde::__private228::Ok(__Field::__field2),
                            "ObjectId" => _serde::__private228::Ok(__Field::__field3),
                            "ObjectSelf" => _serde::__private228::Ok(__Field::__field4),
                            "ObjectInvalid" =>
                                _serde::__private228::Ok(__Field::__field5),
                            "LocationInvalid" =>
                                _serde::__private228::Ok(__Field::__field6),
                            "Json" => _serde::__private228::Ok(__Field::__field7),
                            "Vector" => _serde::__private228::Ok(__Field::__field8),
                            "Raw" => _serde::__private228::Ok(__Field::__field9),
                            _ => {
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"Int" => _serde::__private228::Ok(__Field::__field0),
                            b"Float" => _serde::__private228::Ok(__Field::__field1),
                            b"String" => _serde::__private228::Ok(__Field::__field2),
                            b"ObjectId" => _serde::__private228::Ok(__Field::__field3),
                            b"ObjectSelf" =>
                                _serde::__private228::Ok(__Field::__field4),
                            b"ObjectInvalid" =>
                                _serde::__private228::Ok(__Field::__field5),
                            b"LocationInvalid" =>
                                _serde::__private228::Ok(__Field::__field6),
                            b"Json" => _serde::__private228::Ok(__Field::__field7),
                            b"Vector" => _serde::__private228::Ok(__Field::__field8),
                            b"Raw" => _serde::__private228::Ok(__Field::__field9),
                            _ => {
                                let __value =
                                    &_serde::__private228::from_utf8_lossy(__value);
                                _serde::__private228::Err(_serde::de::Error::unknown_variant(__value,
                                        VARIANTS))
                            }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<BuiltinValue>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = BuiltinValue;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "enum BuiltinValue")
                    }
                    fn visit_enum<__A>(self, __data: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::EnumAccess<'de> {
                        match _serde::de::EnumAccess::variant(__data)? {
                            (__Field::__field0, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<i32>(__variant),
                                    BuiltinValue::Int),
                            (__Field::__field1, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<f32>(__variant),
                                    BuiltinValue::Float),
                            (__Field::__field2, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<String>(__variant),
                                    BuiltinValue::String),
                            (__Field::__field3, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<i32>(__variant),
                                    BuiltinValue::ObjectId),
                            (__Field::__field4, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinValue::ObjectSelf)
                            }
                            (__Field::__field5, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinValue::ObjectInvalid)
                            }
                            (__Field::__field6, __variant) => {
                                _serde::de::VariantAccess::unit_variant(__variant)?;
                                _serde::__private228::Ok(BuiltinValue::LocationInvalid)
                            }
                            (__Field::__field7, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<String>(__variant),
                                    BuiltinValue::Json),
                            (__Field::__field8, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<[f32; 3]>(__variant),
                                    BuiltinValue::Vector),
                            (__Field::__field9, __variant) =>
                                _serde::__private228::Result::map(_serde::de::VariantAccess::newtype_variant::<String>(__variant),
                                    BuiltinValue::Raw),
                        }
                    }
                }
                #[doc(hidden)]
                const VARIANTS: &'static [&'static str] =
                    &["Int", "Float", "String", "ObjectId", "ObjectSelf",
                                "ObjectInvalid", "LocationInvalid", "Json", "Vector",
                                "Raw"];
                _serde::Deserializer::deserialize_enum(__deserializer,
                    "BuiltinValue", VARIANTS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<BuiltinValue>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
38pub enum BuiltinValue {
39    /// Integer literal.
40    Int(i32),
41    /// Floating-point literal.
42    Float(f32),
43    /// String literal.
44    String(String),
45    /// Raw object-id sentinel used for builtin object defaults such as
46    /// `OBJECT_TYPE_INVALID`.
47    ObjectId(i32),
48    /// `OBJECT_SELF`
49    ObjectSelf,
50    /// `OBJECT_INVALID`
51    ObjectInvalid,
52    /// `LOCATION_INVALID`
53    LocationInvalid,
54    /// One JSON default represented in the same textual form upstream stores.
55    Json(String),
56    /// Vector literal.
57    Vector([f32; 3]),
58    /// One builtin value preserved as raw source text when this parser does not
59    /// yet understand its exact typed form.
60    Raw(String),
61}
62
63/// One builtin constant declaration.
64#[derive(#[automatically_derived]
impl ::core::fmt::Debug for BuiltinConstant {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "BuiltinConstant", "name", &self.name, "ty", &self.ty, "value",
            &&self.value)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for BuiltinConstant {
    #[inline]
    fn clone(&self) -> BuiltinConstant {
        BuiltinConstant {
            name: ::core::clone::Clone::clone(&self.name),
            ty: ::core::clone::Clone::clone(&self.ty),
            value: ::core::clone::Clone::clone(&self.value),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BuiltinConstant {
    #[inline]
    fn eq(&self, other: &BuiltinConstant) -> bool {
        self.name == other.name && self.ty == other.ty &&
            self.value == other.value
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for BuiltinConstant {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "BuiltinConstant", false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "ty", &self.ty)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "value", &self.value)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for BuiltinConstant {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "name" => _serde::__private228::Ok(__Field::__field0),
                            "ty" => _serde::__private228::Ok(__Field::__field1),
                            "value" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"name" => _serde::__private228::Ok(__Field::__field0),
                            b"ty" => _serde::__private228::Ok(__Field::__field1),
                            b"value" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<BuiltinConstant>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = BuiltinConstant;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct BuiltinConstant")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct BuiltinConstant with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<BuiltinType>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct BuiltinConstant with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<BuiltinValue>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct BuiltinConstant with 3 elements")),
                            };
                        _serde::__private228::Ok(BuiltinConstant {
                                name: __field0,
                                ty: __field1,
                                value: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<BuiltinType> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<BuiltinValue> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("ty"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<BuiltinType>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("value"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<BuiltinValue>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("name")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("ty")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("value")?,
                            };
                        _serde::__private228::Ok(BuiltinConstant {
                                name: __field0,
                                ty: __field1,
                                value: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["name", "ty", "value"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "BuiltinConstant", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<BuiltinConstant>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
65pub struct BuiltinConstant {
66    /// Constant name.
67    pub name:  String,
68    /// Constant type.
69    pub ty:    BuiltinType,
70    /// Constant value.
71    pub value: BuiltinValue,
72}
73
74/// One builtin function parameter.
75#[derive(#[automatically_derived]
impl ::core::fmt::Debug for BuiltinParameter {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "BuiltinParameter", "name", &self.name, "ty", &self.ty, "default",
            &&self.default)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for BuiltinParameter {
    #[inline]
    fn clone(&self) -> BuiltinParameter {
        BuiltinParameter {
            name: ::core::clone::Clone::clone(&self.name),
            ty: ::core::clone::Clone::clone(&self.ty),
            default: ::core::clone::Clone::clone(&self.default),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BuiltinParameter {
    #[inline]
    fn eq(&self, other: &BuiltinParameter) -> bool {
        self.name == other.name && self.ty == other.ty &&
            self.default == other.default
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for BuiltinParameter {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "BuiltinParameter", false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "ty", &self.ty)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "default", &self.default)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for BuiltinParameter {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "name" => _serde::__private228::Ok(__Field::__field0),
                            "ty" => _serde::__private228::Ok(__Field::__field1),
                            "default" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"name" => _serde::__private228::Ok(__Field::__field0),
                            b"ty" => _serde::__private228::Ok(__Field::__field1),
                            b"default" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<BuiltinParameter>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = BuiltinParameter;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct BuiltinParameter")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct BuiltinParameter with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<BuiltinType>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct BuiltinParameter with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<Option<BuiltinValue>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct BuiltinParameter with 3 elements")),
                            };
                        _serde::__private228::Ok(BuiltinParameter {
                                name: __field0,
                                ty: __field1,
                                default: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<BuiltinType> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<Option<BuiltinValue>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("ty"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<BuiltinType>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("default"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Option<BuiltinValue>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("name")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("ty")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("default")?,
                            };
                        _serde::__private228::Ok(BuiltinParameter {
                                name: __field0,
                                ty: __field1,
                                default: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["name", "ty", "default"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "BuiltinParameter", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<BuiltinParameter>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
76pub struct BuiltinParameter {
77    /// Parameter name.
78    pub name:    String,
79    /// Parameter type.
80    pub ty:      BuiltinType,
81    /// Optional default value.
82    pub default: Option<BuiltinValue>,
83}
84
85/// One builtin function declaration.
86#[derive(#[automatically_derived]
impl ::core::fmt::Debug for BuiltinFunction {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field3_finish(f,
            "BuiltinFunction", "name", &self.name, "return_type",
            &self.return_type, "parameters", &&self.parameters)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for BuiltinFunction {
    #[inline]
    fn clone(&self) -> BuiltinFunction {
        BuiltinFunction {
            name: ::core::clone::Clone::clone(&self.name),
            return_type: ::core::clone::Clone::clone(&self.return_type),
            parameters: ::core::clone::Clone::clone(&self.parameters),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for BuiltinFunction {
    #[inline]
    fn eq(&self, other: &BuiltinFunction) -> bool {
        self.name == other.name && self.return_type == other.return_type &&
            self.parameters == other.parameters
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for BuiltinFunction {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "BuiltinFunction", false as usize + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "name", &self.name)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "return_type", &self.return_type)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "parameters", &self.parameters)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for BuiltinFunction {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field { __field0, __field1, __field2, __ignore, }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "name" => _serde::__private228::Ok(__Field::__field0),
                            "return_type" =>
                                _serde::__private228::Ok(__Field::__field1),
                            "parameters" => _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"name" => _serde::__private228::Ok(__Field::__field0),
                            b"return_type" =>
                                _serde::__private228::Ok(__Field::__field1),
                            b"parameters" =>
                                _serde::__private228::Ok(__Field::__field2),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<BuiltinFunction>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = BuiltinFunction;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct BuiltinFunction")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<String>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct BuiltinFunction with 3 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<BuiltinType>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct BuiltinFunction with 3 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<Vec<BuiltinParameter>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct BuiltinFunction with 3 elements")),
                            };
                        _serde::__private228::Ok(BuiltinFunction {
                                name: __field0,
                                return_type: __field1,
                                parameters: __field2,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<String> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<BuiltinType> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<Vec<BuiltinParameter>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("name"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<String>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("return_type"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<BuiltinType>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("parameters"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<BuiltinParameter>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("name")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("return_type")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("parameters")?,
                            };
                        _serde::__private228::Ok(BuiltinFunction {
                                name: __field0,
                                return_type: __field1,
                                parameters: __field2,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["name", "return_type", "parameters"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "BuiltinFunction", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<BuiltinFunction>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
87pub struct BuiltinFunction {
88    /// Function name.
89    pub name:        String,
90    /// Return type.
91    pub return_type: BuiltinType,
92    /// Parameters in declaration order.
93    pub parameters:  Vec<BuiltinParameter>,
94}
95
96/// Parsed builtin declarations from `nwscript.nss`.
97#[derive(#[automatically_derived]
impl ::core::fmt::Debug for LangSpec {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        ::core::fmt::Formatter::debug_struct_field4_finish(f, "LangSpec",
            "engine_num_structures", &self.engine_num_structures,
            "engine_structures", &self.engine_structures, "constants",
            &self.constants, "functions", &&self.functions)
    }
}Debug, #[automatically_derived]
impl ::core::clone::Clone for LangSpec {
    #[inline]
    fn clone(&self) -> LangSpec {
        LangSpec {
            engine_num_structures: ::core::clone::Clone::clone(&self.engine_num_structures),
            engine_structures: ::core::clone::Clone::clone(&self.engine_structures),
            constants: ::core::clone::Clone::clone(&self.constants),
            functions: ::core::clone::Clone::clone(&self.functions),
        }
    }
}Clone, #[automatically_derived]
impl ::core::cmp::PartialEq for LangSpec {
    #[inline]
    fn eq(&self, other: &LangSpec) -> bool {
        self.engine_num_structures == other.engine_num_structures &&
                    self.engine_structures == other.engine_structures &&
                self.constants == other.constants &&
            self.functions == other.functions
    }
}PartialEq, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl _serde::Serialize for LangSpec {
            fn serialize<__S>(&self, __serializer: __S)
                -> _serde::__private228::Result<__S::Ok, __S::Error> where
                __S: _serde::Serializer {
                let mut __serde_state =
                    _serde::Serializer::serialize_struct(__serializer,
                            "LangSpec", false as usize + 1 + 1 + 1 + 1)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "engine_num_structures", &self.engine_num_structures)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "engine_structures", &self.engine_structures)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "constants", &self.constants)?;
                _serde::ser::SerializeStruct::serialize_field(&mut __serde_state,
                        "functions", &self.functions)?;
                _serde::ser::SerializeStruct::end(__serde_state)
            }
        }
    };Serialize, #[doc(hidden)]
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications,
clippy :: absolute_paths,)]
const _: () =
    {
        #[allow(unused_extern_crates, clippy :: useless_attribute)]
        extern crate serde as _serde;
        ;
        #[automatically_derived]
        impl<'de> _serde::Deserialize<'de> for LangSpec {
            fn deserialize<__D>(__deserializer: __D)
                -> _serde::__private228::Result<Self, __D::Error> where
                __D: _serde::Deserializer<'de> {
                #[allow(non_camel_case_types)]
                #[doc(hidden)]
                enum __Field {
                    __field0,
                    __field1,
                    __field2,
                    __field3,
                    __ignore,
                }
                #[doc(hidden)]
                struct __FieldVisitor;
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __FieldVisitor {
                    type Value = __Field;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "field identifier")
                    }
                    fn visit_u64<__E>(self, __value: u64)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            0u64 => _serde::__private228::Ok(__Field::__field0),
                            1u64 => _serde::__private228::Ok(__Field::__field1),
                            2u64 => _serde::__private228::Ok(__Field::__field2),
                            3u64 => _serde::__private228::Ok(__Field::__field3),
                            _ => _serde::__private228::Ok(__Field::__ignore),
                        }
                    }
                    fn visit_str<__E>(self, __value: &str)
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            "engine_num_structures" =>
                                _serde::__private228::Ok(__Field::__field0),
                            "engine_structures" =>
                                _serde::__private228::Ok(__Field::__field1),
                            "constants" => _serde::__private228::Ok(__Field::__field2),
                            "functions" => _serde::__private228::Ok(__Field::__field3),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                    fn visit_bytes<__E>(self, __value: &[u8])
                        -> _serde::__private228::Result<Self::Value, __E> where
                        __E: _serde::de::Error {
                        match __value {
                            b"engine_num_structures" =>
                                _serde::__private228::Ok(__Field::__field0),
                            b"engine_structures" =>
                                _serde::__private228::Ok(__Field::__field1),
                            b"constants" => _serde::__private228::Ok(__Field::__field2),
                            b"functions" => _serde::__private228::Ok(__Field::__field3),
                            _ => { _serde::__private228::Ok(__Field::__ignore) }
                        }
                    }
                }
                #[automatically_derived]
                impl<'de> _serde::Deserialize<'de> for __Field {
                    #[inline]
                    fn deserialize<__D>(__deserializer: __D)
                        -> _serde::__private228::Result<Self, __D::Error> where
                        __D: _serde::Deserializer<'de> {
                        _serde::Deserializer::deserialize_identifier(__deserializer,
                            __FieldVisitor)
                    }
                }
                #[doc(hidden)]
                struct __Visitor<'de> {
                    marker: _serde::__private228::PhantomData<LangSpec>,
                    lifetime: _serde::__private228::PhantomData<&'de ()>,
                }
                #[automatically_derived]
                impl<'de> _serde::de::Visitor<'de> for __Visitor<'de> {
                    type Value = LangSpec;
                    fn expecting(&self,
                        __formatter: &mut _serde::__private228::Formatter)
                        -> _serde::__private228::fmt::Result {
                        _serde::__private228::Formatter::write_str(__formatter,
                            "struct LangSpec")
                    }
                    #[inline]
                    fn visit_seq<__A>(self, mut __seq: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::SeqAccess<'de> {
                        let __field0 =
                            match _serde::de::SeqAccess::next_element::<usize>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(0usize,
                                                &"struct LangSpec with 4 elements")),
                            };
                        let __field1 =
                            match _serde::de::SeqAccess::next_element::<Vec<String>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(1usize,
                                                &"struct LangSpec with 4 elements")),
                            };
                        let __field2 =
                            match _serde::de::SeqAccess::next_element::<Vec<BuiltinConstant>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(2usize,
                                                &"struct LangSpec with 4 elements")),
                            };
                        let __field3 =
                            match _serde::de::SeqAccess::next_element::<Vec<BuiltinFunction>>(&mut __seq)?
                                {
                                _serde::__private228::Some(__value) => __value,
                                _serde::__private228::None =>
                                    return _serde::__private228::Err(_serde::de::Error::invalid_length(3usize,
                                                &"struct LangSpec with 4 elements")),
                            };
                        _serde::__private228::Ok(LangSpec {
                                engine_num_structures: __field0,
                                engine_structures: __field1,
                                constants: __field2,
                                functions: __field3,
                            })
                    }
                    #[inline]
                    fn visit_map<__A>(self, mut __map: __A)
                        -> _serde::__private228::Result<Self::Value, __A::Error>
                        where __A: _serde::de::MapAccess<'de> {
                        let mut __field0: _serde::__private228::Option<usize> =
                            _serde::__private228::None;
                        let mut __field1:
                                _serde::__private228::Option<Vec<String>> =
                            _serde::__private228::None;
                        let mut __field2:
                                _serde::__private228::Option<Vec<BuiltinConstant>> =
                            _serde::__private228::None;
                        let mut __field3:
                                _serde::__private228::Option<Vec<BuiltinFunction>> =
                            _serde::__private228::None;
                        while let _serde::__private228::Some(__key) =
                                _serde::de::MapAccess::next_key::<__Field>(&mut __map)? {
                            match __key {
                                __Field::__field0 => {
                                    if _serde::__private228::Option::is_some(&__field0) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("engine_num_structures"));
                                    }
                                    __field0 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<usize>(&mut __map)?);
                                }
                                __Field::__field1 => {
                                    if _serde::__private228::Option::is_some(&__field1) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("engine_structures"));
                                    }
                                    __field1 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<String>>(&mut __map)?);
                                }
                                __Field::__field2 => {
                                    if _serde::__private228::Option::is_some(&__field2) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("constants"));
                                    }
                                    __field2 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<BuiltinConstant>>(&mut __map)?);
                                }
                                __Field::__field3 => {
                                    if _serde::__private228::Option::is_some(&__field3) {
                                        return _serde::__private228::Err(<__A::Error as
                                                        _serde::de::Error>::duplicate_field("functions"));
                                    }
                                    __field3 =
                                        _serde::__private228::Some(_serde::de::MapAccess::next_value::<Vec<BuiltinFunction>>(&mut __map)?);
                                }
                                _ => {
                                    let _ =
                                        _serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)?;
                                }
                            }
                        }
                        let __field0 =
                            match __field0 {
                                _serde::__private228::Some(__field0) => __field0,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("engine_num_structures")?,
                            };
                        let __field1 =
                            match __field1 {
                                _serde::__private228::Some(__field1) => __field1,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("engine_structures")?,
                            };
                        let __field2 =
                            match __field2 {
                                _serde::__private228::Some(__field2) => __field2,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("constants")?,
                            };
                        let __field3 =
                            match __field3 {
                                _serde::__private228::Some(__field3) => __field3,
                                _serde::__private228::None =>
                                    _serde::__private228::de::missing_field("functions")?,
                            };
                        _serde::__private228::Ok(LangSpec {
                                engine_num_structures: __field0,
                                engine_structures: __field1,
                                constants: __field2,
                                functions: __field3,
                            })
                    }
                }
                #[doc(hidden)]
                const FIELDS: &'static [&'static str] =
                    &["engine_num_structures", "engine_structures", "constants",
                                "functions"];
                _serde::Deserializer::deserialize_struct(__deserializer,
                    "LangSpec", FIELDS,
                    __Visitor {
                        marker: _serde::__private228::PhantomData::<LangSpec>,
                        lifetime: _serde::__private228::PhantomData,
                    })
            }
        }
    };Deserialize)]
98pub struct LangSpec {
99    /// Number declared by `ENGINE_NUM_STRUCTURES`.
100    pub engine_num_structures: usize,
101    /// Engine structure names in index order.
102    pub engine_structures:     Vec<String>,
103    /// Builtin constants in declaration order.
104    pub constants:             Vec<BuiltinConstant>,
105    /// Builtin functions in declaration order.
106    pub functions:             Vec<BuiltinFunction>,
107}
108
109/// Errors returned while bootstrapping the builtin language spec.
110#[derive(#[automatically_derived]
impl ::core::fmt::Debug for LangSpecError {
    #[inline]
    fn fmt(&self, f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
        match self {
            LangSpecError::Source(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Source",
                    &__self_0),
            LangSpecError::Lex(__self_0) =>
                ::core::fmt::Formatter::debug_tuple_field1_finish(f, "Lex",
                    &__self_0),
            LangSpecError::Parse { code: __self_0, message: __self_1 } =>
                ::core::fmt::Formatter::debug_struct_field2_finish(f, "Parse",
                    "code", __self_0, "message", &__self_1),
        }
    }
}Debug)]
111pub enum LangSpecError {
112    /// Source loading failure.
113    Source(SourceError),
114    /// Lexing failure.
115    Lex(LexerError),
116    /// The language specification text was malformed.
117    Parse {
118        /// Upstream-aligned compiler error code.
119        code:    CompilerErrorCode,
120        /// Human-readable message.
121        message: String,
122    },
123}
124
125impl LangSpecError {
126    fn parse(message: impl Into<String>) -> Self {
127        Self::Parse {
128            code:    CompilerErrorCode::ParsingIdentifierList,
129            message: message.into(),
130        }
131    }
132}
133
134impl fmt::Display for LangSpecError {
135    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
136        match self {
137            Self::Source(error) => error.fmt(f),
138            Self::Lex(error) => error.fmt(f),
139            Self::Parse {
140                code,
141                message,
142            } => f.write_fmt(format_args!("{1} ({0})", code.code(), message))write!(f, "{message} ({})", code.code()),
143        }
144    }
145}
146
147impl Error for LangSpecError {}
148
149impl From<SourceError> for LangSpecError {
150    fn from(value: SourceError) -> Self {
151        Self::Source(value)
152    }
153}
154
155impl From<LexerError> for LangSpecError {
156    fn from(value: LexerError) -> Self {
157        Self::Lex(value)
158    }
159}
160
161/// Loads `nwscript.nss` through a source resolver and parses the builtin
162/// declarations.
163///
164/// # Errors
165///
166/// Returns [`LangSpecError`] if the source cannot be loaded or parsed.
167pub fn load_langspec<R: ScriptResolver + ?Sized>(
168    resolver: &R,
169    script_name: &str,
170    options: SourceLoadOptions,
171) -> Result<LangSpec, LangSpecError> {
172    let bundle =
173        load_source_bundle(resolver, script_name, options).map_err(|error| match error {
174            crate::PreprocessError::Source(source) => LangSpecError::Source(source),
175            crate::PreprocessError::Lex(lex) => LangSpecError::Lex(lex),
176        })?;
177    parse_langspec_from_source_map(&bundle.source_map, bundle.root_id)
178}
179
180/// Parses builtin declarations from one already-loaded source file.
181///
182/// # Errors
183///
184/// Returns [`LangSpecError`] if parsing fails.
185pub fn parse_langspec(source_name: &str, input: &str) -> Result<LangSpec, LangSpecError> {
186    parse_langspec_bytes(source_name, input.as_bytes())
187}
188
189/// Parses builtin declarations from one already-loaded byte buffer.
190///
191/// # Errors
192///
193/// Returns [`LangSpecError`] if parsing fails.
194pub fn parse_langspec_bytes(source_name: &str, input: &[u8]) -> Result<LangSpec, LangSpecError> {
195    let mut source_map = SourceMap::new();
196    let root_id = source_map.add_file(source_name, input);
197    parse_langspec_from_source_map(&source_map, root_id)
198}
199
200/// Parses builtin declarations from `root_id` in `source_map`.
201///
202/// # Errors
203///
204/// Returns [`LangSpecError`] if parsing fails.
205pub fn parse_langspec_from_source_map(
206    source_map: &SourceMap,
207    root_id: crate::SourceId,
208) -> Result<LangSpec, LangSpecError> {
209    let source = source_map
210        .get(root_id)
211        .ok_or_else(|| LangSpecError::parse("missing root source file for langspec parse"))?;
212    let tokens = lex_source(source)?;
213    LangSpecParser::new(source, tokens).parse()
214}
215
216struct LangSpecParser<'a> {
217    source:                &'a SourceFile,
218    tokens:                Vec<Token>,
219    position:              usize,
220    engine_num_structures: usize,
221    engine_structures:     Vec<String>,
222    constants:             Vec<BuiltinConstant>,
223    functions:             Vec<BuiltinFunction>,
224    constant_values:       HashMap<String, BuiltinValue>,
225}
226
227impl<'a> LangSpecParser<'a> {
228    fn new(source: &'a SourceFile, tokens: Vec<Token>) -> Self {
229        Self {
230            source,
231            tokens,
232            position: 0,
233            engine_num_structures: 0,
234            engine_structures: Vec::new(),
235            constants: Vec::new(),
236            functions: Vec::new(),
237            constant_values: HashMap::new(),
238        }
239    }
240
241    fn parse(mut self) -> Result<LangSpec, LangSpecError> {
242        while !self.at_eof() {
243            if self.matches_keyword(Keyword::Define) {
244                self.parse_define()?;
245            } else {
246                self.parse_declaration()?;
247            }
248        }
249
250        Ok(LangSpec {
251            engine_num_structures: self.engine_num_structures,
252            engine_structures:     self.engine_structures,
253            constants:             self.constants,
254            functions:             self.functions,
255        })
256    }
257
258    fn parse_define(&mut self) -> Result<(), LangSpecError> {
259        self.expect_keyword(Keyword::Define)?;
260        if self.matches_keyword(Keyword::EngineNumStructuresDefinition) {
261            self.advance();
262            let value = self.expect_integer_literal()?;
263            self.engine_num_structures =
264                usize::try_from(value).map_err(|error| LangSpecError::parse(error.to_string()))?;
265            return Ok(());
266        }
267
268        let token = self
269            .advance()
270            .ok_or_else(|| LangSpecError::parse("unexpected EOF after #define"))?;
271        let define_line = self.line_number_for_token(&token);
272        let index = match &token.kind {
273            TokenKind::Identifier | TokenKind::Keyword(Keyword::EngineStructureDefinition) => {
274                let Some(index) = parse_engine_structure_define_index(&token.text) else {
275                    self.skip_line(define_line);
276                    return Ok(());
277                };
278                index
279            }
280            _ => {
281                self.skip_line(define_line);
282                return Ok(());
283            }
284        };
285
286        let structure_name = self.expect_identifier_like_name()?;
287        if self.engine_structures.len() <= index {
288            self.engine_structures.resize(index + 1, String::new());
289        }
290        if let Some(slot) = self.engine_structures.get_mut(index) {
291            *slot = structure_name;
292        }
293        Ok(())
294    }
295
296    fn parse_declaration(&mut self) -> Result<(), LangSpecError> {
297        let ty = self.parse_type()?;
298        let name = self.expect_identifier_like_name()?;
299
300        if self.matches_kind(&TokenKind::Assign) {
301            self.advance();
302            let value = self.parse_value_for_type_or_raw(&ty, &[TokenKind::Semicolon])?;
303            self.expect_kind(TokenKind::Semicolon)?;
304            self.constant_values.insert(name.clone(), value.clone());
305            self.constants.push(BuiltinConstant {
306                name,
307                ty,
308                value,
309            });
310            return Ok(());
311        }
312
313        self.expect_kind(TokenKind::LeftParen)?;
314        let parameters = self.parse_parameters()?;
315        self.expect_kind(TokenKind::RightParen)?;
316        self.expect_kind(TokenKind::Semicolon)?;
317        self.functions.push(BuiltinFunction {
318            name,
319            return_type: ty,
320            parameters,
321        });
322        Ok(())
323    }
324
325    fn parse_parameters(&mut self) -> Result<Vec<BuiltinParameter>, LangSpecError> {
326        let mut parameters = Vec::new();
327        while !self.matches_kind(&TokenKind::RightParen) {
328            let ty = self.parse_type()?;
329            let name = self.expect_identifier_like_name()?;
330            let default =
331                if self.matches_kind(&TokenKind::Assign) {
332                    self.advance();
333                    Some(self.parse_value_for_type_or_raw(
334                        &ty,
335                        &[TokenKind::Comma, TokenKind::RightParen],
336                    )?)
337                } else {
338                    None
339                };
340            parameters.push(BuiltinParameter {
341                name,
342                ty,
343                default,
344            });
345
346            if self.matches_kind(&TokenKind::Comma) {
347                self.advance();
348            } else {
349                break;
350            }
351        }
352        Ok(parameters)
353    }
354
355    fn parse_type(&mut self) -> Result<BuiltinType, LangSpecError> {
356        let token = self
357            .peek()
358            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing type"))?;
359        let parsed = match &token.kind {
360            TokenKind::Keyword(Keyword::Int) => Some(BuiltinType::Int),
361            TokenKind::Keyword(Keyword::Float) => Some(BuiltinType::Float),
362            TokenKind::Keyword(Keyword::String) => Some(BuiltinType::String),
363            TokenKind::Keyword(Keyword::Object) => Some(BuiltinType::Object),
364            TokenKind::Keyword(Keyword::Void) => Some(BuiltinType::Void),
365            TokenKind::Keyword(Keyword::Action) => Some(BuiltinType::Action),
366            TokenKind::Keyword(Keyword::Vector) => Some(BuiltinType::Vector),
367            TokenKind::Identifier => Some(BuiltinType::EngineStructure(token.text.clone())),
368            _ => None,
369        };
370        if let Some(parsed) = parsed {
371            self.advance();
372            Ok(parsed)
373        } else {
374            Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported builtin type token {0:?}",
                token.kind))
    })format!(
375                "unsupported builtin type token {:?}",
376                token.kind
377            )))
378        }
379    }
380
381    fn parse_value_for_type(&mut self, ty: &BuiltinType) -> Result<BuiltinValue, LangSpecError> {
382        match ty {
383            BuiltinType::Int => self.parse_int_like_value().map(BuiltinValue::Int),
384            BuiltinType::Float => self.parse_float_like_value().map(BuiltinValue::Float),
385            BuiltinType::String => self.parse_string_like_value().map(BuiltinValue::String),
386            BuiltinType::Object => self.parse_object_default(),
387            BuiltinType::Vector => self.parse_vector_value(),
388            BuiltinType::EngineStructure(name) if name.eq_ignore_ascii_case("location") => {
389                self.parse_location_default()
390            }
391            BuiltinType::EngineStructure(name) if name.eq_ignore_ascii_case("json") => {
392                self.parse_json_default()
393            }
394            _ => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported builtin default value for type {0:?}",
                ty))
    })format!(
395                "unsupported builtin default value for type {ty:?}"
396            ))),
397        }
398    }
399
400    fn parse_value_for_type_or_raw(
401        &mut self,
402        ty: &BuiltinType,
403        terminators: &[TokenKind],
404    ) -> Result<BuiltinValue, LangSpecError> {
405        let checkpoint = self.position;
406        match self.parse_value_for_type(ty) {
407            Ok(value) => Ok(value),
408            Err(_error) => {
409                self.position = checkpoint;
410                self.parse_raw_value_until(terminators)
411                    .map(BuiltinValue::Raw)
412            }
413        }
414    }
415
416    fn parse_raw_value_until(
417        &mut self,
418        terminators: &[TokenKind],
419    ) -> Result<String, LangSpecError> {
420        let first = self
421            .peek()
422            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing builtin value"))?;
423        let start = first.span.start;
424        let mut end = first.span.end;
425        let mut paren_depth = 0usize;
426        let mut bracket_depth = 0usize;
427        let mut brace_depth = 0usize;
428        let mut consumed = false;
429
430        while let Some(token) = self.peek() {
431            if paren_depth == 0
432                && bracket_depth == 0
433                && brace_depth == 0
434                && terminators.iter().any(|kind| kind == &token.kind)
435            {
436                break;
437            }
438
439            consumed = true;
440            end = token.span.end;
441            match token.kind {
442                TokenKind::LeftParen => paren_depth += 1,
443                TokenKind::RightParen => paren_depth = paren_depth.saturating_sub(1),
444                TokenKind::LeftSquareBracket => bracket_depth += 1,
445                TokenKind::RightSquareBracket => bracket_depth = bracket_depth.saturating_sub(1),
446                TokenKind::LeftBrace => brace_depth += 1,
447                TokenKind::RightBrace => brace_depth = brace_depth.saturating_sub(1),
448                _ => {}
449            }
450            self.advance();
451        }
452
453        if !consumed {
454            return Err(LangSpecError::parse("missing builtin value"));
455        }
456
457        let span = Span::new(self.source.id, start, end);
458        let raw = self
459            .source
460            .span_text(span)
461            .ok_or_else(|| LangSpecError::parse("invalid raw builtin value span"))?
462            .trim()
463            .to_string();
464
465        if raw.is_empty() {
466            return Err(LangSpecError::parse("missing builtin value"));
467        }
468
469        Ok(raw)
470    }
471
472    fn parse_int_like_value(&mut self) -> Result<i32, LangSpecError> {
473        let sign = if self.matches_kind(&TokenKind::Minus) {
474            self.advance();
475            -1
476        } else {
477            1
478        };
479
480        let token = self
481            .advance()
482            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing integer value"))?;
483        let value = match token.kind {
484            TokenKind::Integer => parse_wrapping_decimal_i32(&token.text).map_err(|_error| {
485                LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid integer literal {0:?}",
                token.text))
    })format!("invalid integer literal {:?}", token.text))
486            })?,
487            TokenKind::HexInteger => parse_prefixed_i32(&token.text, 16)?,
488            TokenKind::BinaryInteger => parse_prefixed_i32(&token.text, 2)?,
489            TokenKind::OctalInteger => parse_prefixed_i32(&token.text, 8)?,
490            TokenKind::Identifier => match self.constant_values.get(&token.text) {
491                Some(BuiltinValue::Int(value)) => *value,
492                Some(_) => {
493                    return Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("constant {0:?} is not an integer",
                token.text))
    })format!(
494                        "constant {:?} is not an integer",
495                        token.text
496                    )));
497                }
498                None => {
499                    return Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown integer constant reference {0:?}",
                token.text))
    })format!(
500                        "unknown integer constant reference {:?}",
501                        token.text
502                    )));
503                }
504            },
505            _ => {
506                return Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported integer literal token {0:?}",
                token.kind))
    })format!(
507                    "unsupported integer literal token {:?}",
508                    token.kind
509                )));
510            }
511        };
512        Ok(sign * value)
513    }
514
515    #[allow(clippy::cast_precision_loss)]
516    fn parse_float_like_value(&mut self) -> Result<f32, LangSpecError> {
517        let sign = if self.matches_kind(&TokenKind::Minus) {
518            self.advance();
519            -1.0f32
520        } else {
521            1.0f32
522        };
523
524        let token = self
525            .advance()
526            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing float value"))?;
527        let value = match token.kind {
528            TokenKind::Float => token.text.parse::<f32>().map_err(|error| {
529                LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid float literal {0:?}: {1}",
                token.text, error))
    })format!("invalid float literal {:?}: {error}", token.text))
530            })?,
531            TokenKind::Integer => token.text.parse::<f32>().map_err(|error| {
532                LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid numeric literal {0:?}: {1}",
                token.text, error))
    })format!("invalid numeric literal {:?}: {error}", token.text))
533            })?,
534            TokenKind::Identifier => match self.constant_values.get(&token.text) {
535                Some(BuiltinValue::Float(value)) => *value,
536                Some(BuiltinValue::Int(value)) => *value as f32,
537                Some(_) => {
538                    return Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("constant {0:?} is not numeric",
                token.text))
    })format!(
539                        "constant {:?} is not numeric",
540                        token.text
541                    )));
542                }
543                None => {
544                    return Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown numeric constant reference {0:?}",
                token.text))
    })format!(
545                        "unknown numeric constant reference {:?}",
546                        token.text
547                    )));
548                }
549            },
550            _ => {
551                return Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported float literal token {0:?}",
                token.kind))
    })format!(
552                    "unsupported float literal token {:?}",
553                    token.kind
554                )));
555            }
556        };
557        Ok(sign * value)
558    }
559
560    fn parse_string_like_value(&mut self) -> Result<String, LangSpecError> {
561        let token = self
562            .advance()
563            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing string value"))?;
564        match token.kind {
565            TokenKind::String => Ok(token.text),
566            TokenKind::Identifier => match self.constant_values.get(&token.text) {
567                Some(BuiltinValue::String(value)) => Ok(value.clone()),
568                Some(_) => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("constant {0:?} is not a string",
                token.text))
    })format!(
569                    "constant {:?} is not a string",
570                    token.text
571                ))),
572                None => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown string constant reference {0:?}",
                token.text))
    })format!(
573                    "unknown string constant reference {:?}",
574                    token.text
575                ))),
576            },
577            _ => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported string literal token {0:?}",
                token.kind))
    })format!(
578                "unsupported string literal token {:?}",
579                token.kind
580            ))),
581        }
582    }
583
584    fn parse_object_default(&mut self) -> Result<BuiltinValue, LangSpecError> {
585        let token = self
586            .advance()
587            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing object default"))?;
588        match token.kind {
589            TokenKind::Keyword(Keyword::ObjectSelf) => Ok(BuiltinValue::ObjectSelf),
590            TokenKind::Keyword(Keyword::ObjectInvalid) => Ok(BuiltinValue::ObjectInvalid),
591            TokenKind::Identifier => match self.constant_values.get(&token.text) {
592                Some(BuiltinValue::Int(value)) => Ok(BuiltinValue::ObjectId(*value)),
593                Some(BuiltinValue::ObjectSelf) => Ok(BuiltinValue::ObjectSelf),
594                Some(BuiltinValue::ObjectInvalid) => Ok(BuiltinValue::ObjectInvalid),
595                Some(_) => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("constant {0:?} is not an object default",
                token.text))
    })format!(
596                    "constant {:?} is not an object default",
597                    token.text
598                ))),
599                None => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unknown object constant reference {0:?}",
                token.text))
    })format!(
600                    "unknown object constant reference {:?}",
601                    token.text
602                ))),
603            },
604            _ => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported object default token {0:?}",
                token.kind))
    })format!(
605                "unsupported object default token {:?}",
606                token.kind
607            ))),
608        }
609    }
610
611    fn parse_location_default(&mut self) -> Result<BuiltinValue, LangSpecError> {
612        let token = self
613            .advance()
614            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing location default"))?;
615        match token.kind {
616            TokenKind::Keyword(Keyword::LocationInvalid) => Ok(BuiltinValue::LocationInvalid),
617            _ => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported location default token {0:?}",
                token.kind))
    })format!(
618                "unsupported location default token {:?}",
619                token.kind
620            ))),
621        }
622    }
623
624    fn parse_json_default(&mut self) -> Result<BuiltinValue, LangSpecError> {
625        let token = self
626            .advance()
627            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing json default"))?;
628        match token.kind {
629            TokenKind::Keyword(Keyword::JsonNull) => Ok(BuiltinValue::Json("null".to_string())),
630            TokenKind::Keyword(Keyword::JsonFalse) => Ok(BuiltinValue::Json("false".to_string())),
631            TokenKind::Keyword(Keyword::JsonTrue) => Ok(BuiltinValue::Json("true".to_string())),
632            TokenKind::Keyword(Keyword::JsonObject) => Ok(BuiltinValue::Json("{}".to_string())),
633            TokenKind::Keyword(Keyword::JsonArray) => Ok(BuiltinValue::Json("[]".to_string())),
634            TokenKind::Keyword(Keyword::JsonString) => Ok(BuiltinValue::Json("\"\"".to_string())),
635            _ => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("unsupported json default token {0:?}",
                token.kind))
    })format!(
636                "unsupported json default token {:?}",
637                token.kind
638            ))),
639        }
640    }
641
642    fn parse_vector_value(&mut self) -> Result<BuiltinValue, LangSpecError> {
643        self.expect_kind(TokenKind::LeftSquareBracket)?;
644        let x = self.parse_float_like_value()?;
645        self.expect_kind(TokenKind::Comma)?;
646        let y = self.parse_float_like_value()?;
647        self.expect_kind(TokenKind::Comma)?;
648        let z = self.parse_float_like_value()?;
649        self.expect_kind(TokenKind::RightSquareBracket)?;
650        Ok(BuiltinValue::Vector([x, y, z]))
651    }
652
653    fn expect_integer_literal(&mut self) -> Result<i32, LangSpecError> {
654        self.parse_int_like_value()
655    }
656
657    fn expect_identifier_like_name(&mut self) -> Result<String, LangSpecError> {
658        let token = self
659            .advance()
660            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing identifier"))?;
661        match token.kind {
662            TokenKind::Identifier | TokenKind::Keyword(Keyword::EngineStructureDefinition) => {
663                Ok(token.text)
664            }
665            _ => Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected identifier, found {0:?}",
                token.kind))
    })format!(
666                "expected identifier, found {:?}",
667                token.kind
668            ))),
669        }
670    }
671
672    fn expect_keyword(&mut self, keyword: Keyword) -> Result<(), LangSpecError> {
673        let token = self
674            .advance()
675            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing keyword"))?;
676        if token.kind == TokenKind::Keyword(keyword) {
677            Ok(())
678        } else {
679            Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected keyword {0:?}, found {1:?}",
                keyword, token.kind))
    })format!(
680                "expected keyword {:?}, found {:?}",
681                keyword, token.kind
682            )))
683        }
684    }
685
686    #[allow(clippy::needless_pass_by_value)]
687    fn expect_kind(&mut self, kind: TokenKind) -> Result<(), LangSpecError> {
688        let token = self
689            .advance()
690            .ok_or_else(|| LangSpecError::parse("unexpected EOF while parsing token"))?;
691        if token.kind == kind {
692            Ok(())
693        } else {
694            Err(LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("expected token {0:?}, found {1:?}",
                kind, token.kind))
    })format!(
695                "expected token {:?}, found {:?}",
696                kind, token.kind
697            )))
698        }
699    }
700
701    fn matches_keyword(&self, keyword: Keyword) -> bool {
702        self.peek()
703            .is_some_and(|token| token.kind == TokenKind::Keyword(keyword))
704    }
705
706    fn matches_kind(&self, kind: &TokenKind) -> bool {
707        self.peek().is_some_and(|token| &token.kind == kind)
708    }
709
710    fn at_eof(&self) -> bool {
711        self.peek().is_none_or(|token| token.kind == TokenKind::Eof)
712    }
713
714    fn peek(&self) -> Option<&Token> {
715        self.tokens.get(self.position)
716    }
717
718    fn advance(&mut self) -> Option<Token> {
719        let token = self.tokens.get(self.position).cloned()?;
720        self.position += 1;
721        Some(token)
722    }
723
724    fn line_number_for_token(&self, token: &Token) -> Option<usize> {
725        self.source
726            .location(token.span.start)
727            .map(|location| location.line)
728    }
729
730    fn skip_line(&mut self, line: Option<usize>) {
731        let Some(line) = line else {
732            return;
733        };
734
735        while let Some(token) = self.peek() {
736            if token.kind == TokenKind::Eof {
737                break;
738            }
739            if self.line_number_for_token(token) != Some(line) {
740                break;
741            }
742            self.position += 1;
743        }
744    }
745}
746
747fn parse_engine_structure_define_index(input: &str) -> Option<usize> {
748    input
749        .strip_prefix("ENGINE_STRUCTURE_")
750        .and_then(|value| value.parse::<usize>().ok())
751}
752
753fn parse_prefixed_i32(input: &str, radix: u32) -> Result<i32, LangSpecError> {
754    parse_wrapping_prefixed_i32(input, radix)
755        .map_err(|_error| LangSpecError::parse(::alloc::__export::must_use({
        ::alloc::fmt::format(format_args!("invalid integer literal {0:?}",
                input))
    })format!("invalid integer literal {input:?}")))
756}
757
758#[cfg(test)]
759mod tests {
760    use crate::{
761        BuiltinType, BuiltinValue, DEFAULT_LANGSPEC_SCRIPT_NAME, InMemoryScriptResolver,
762        SourceLoadOptions, load_langspec, parse_langspec,
763    };
764
765    #[test]
766    fn parses_engine_structures_constants_and_functions() {
767        let spec = parse_langspec(
768            "nwscript.nss",
769            r#"
770#define ENGINE_NUM_STRUCTURES 3
771#define ENGINE_STRUCTURE_0 effect
772#define ENGINE_STRUCTURE_1 location
773#define ENGINE_STRUCTURE_2 json
774
775int TRUE = 1;
776int FALSE = 0;
777int OBJECT_TYPE_INVALID = 32767;
778float PI = 3.141592;
779string HELLO = "hello";
780
781void TestDefaults(
782    int bEnabled = FALSE,
783    float fRadians = PI,
784    string sLabel = HELLO,
785    object oTarget = OBJECT_SELF,
786    object oTokenTarget = OBJECT_TYPE_INVALID,
787    location lWhere = LOCATION_INVALID,
788    json jData = JSON_OBJECT,
789    vector vPos = [1.0, 2.0, 3.0]
790);
791
792effect EffectDamage(int nAmount);
793"#,
794        );
795
796        let spec = spec.ok();
797        assert_eq!(
798            spec.as_ref().map(|spec| spec.engine_structures.clone()),
799            Some(vec![
800                "effect".to_string(),
801                "location".to_string(),
802                "json".to_string()
803            ])
804        );
805        assert_eq!(spec.as_ref().map(|spec| spec.constants.len()), Some(5));
806        assert_eq!(spec.as_ref().map(|spec| spec.functions.len()), Some(2));
807
808        let defaults = spec
809            .as_ref()
810            .and_then(|spec| {
811                spec.functions
812                    .iter()
813                    .find(|function| function.name == "TestDefaults")
814            })
815            .map(|function| {
816                function
817                    .parameters
818                    .iter()
819                    .map(|param| param.default.clone())
820                    .collect::<Vec<_>>()
821            });
822
823        assert_eq!(
824            defaults,
825            Some(vec![
826                Some(BuiltinValue::Int(0)),
827                Some(BuiltinValue::Float(3_141_592.0_f32 / 1_000_000.0_f32)),
828                Some(BuiltinValue::String("hello".to_string())),
829                Some(BuiltinValue::ObjectSelf),
830                Some(BuiltinValue::ObjectId(32767)),
831                Some(BuiltinValue::LocationInvalid),
832                Some(BuiltinValue::Json("{}".to_string())),
833                Some(BuiltinValue::Vector([1.0, 2.0, 3.0])),
834            ])
835        );
836
837        let return_type = spec
838            .as_ref()
839            .and_then(|spec| {
840                spec.functions
841                    .iter()
842                    .find(|function| function.name == "EffectDamage")
843            })
844            .map(|function| function.return_type.clone());
845        assert_eq!(
846            return_type,
847            Some(BuiltinType::EngineStructure("effect".to_string()))
848        );
849    }
850
851    #[test]
852    fn loads_langspec_through_resolver() {
853        let mut resolver = InMemoryScriptResolver::new();
854        resolver.insert_source(
855            DEFAULT_LANGSPEC_SCRIPT_NAME,
856            r#"
857#define ENGINE_NUM_STRUCTURES 1
858#define ENGINE_STRUCTURE_0 effect
859int TRUE = 1;
860effect EffectFoo(int bValue = TRUE);
861"#,
862        );
863
864        let spec = load_langspec(
865            &resolver,
866            DEFAULT_LANGSPEC_SCRIPT_NAME,
867            SourceLoadOptions::default(),
868        );
869
870        assert_eq!(spec.ok().map(|spec| spec.functions.len()), Some(1));
871    }
872
873    #[test]
874    fn ignores_unknown_define_lines() {
875        let spec = parse_langspec(
876            "nwscript.nss",
877            r#"
878#define ENGINE_NUM_STRUCTURES 1
879#define ENGINE_STRUCTURE_0 effect
880#define FUTURE_FEATURE (1 << 5)
881#define YET_ANOTHER_FEATURE SOME_IDENTIFIER
882
883effect EffectDamage(int nAmount);
884"#,
885        )
886        .expect("langspec should parse");
887
888        assert_eq!(spec.engine_structures, vec!["effect".to_string()]);
889        assert_eq!(spec.functions.len(), 1);
890        assert_eq!(
891            spec.functions
892                .first()
893                .expect("EffectDamage should be present")
894                .return_type,
895            BuiltinType::EngineStructure("effect".to_string())
896        );
897    }
898
899    #[test]
900    fn accepts_identifier_typed_builtins_before_structure_defines() {
901        let spec = parse_langspec(
902            "nwscript.nss",
903            r#"
904#define ENGINE_NUM_STRUCTURES 1
905
906json JsonObject();
907
908#define ENGINE_STRUCTURE_0 json
909"#,
910        )
911        .expect("langspec should parse");
912
913        assert_eq!(spec.functions.len(), 1);
914        assert_eq!(
915            spec.functions
916                .first()
917                .expect("JsonObject should be present")
918                .return_type,
919            BuiltinType::EngineStructure("json".to_string())
920        );
921        assert_eq!(spec.engine_structures, vec!["json".to_string()]);
922    }
923
924    #[test]
925    fn preserves_unknown_builtin_values_as_raw_text() {
926        let spec = parse_langspec(
927            "nwscript.nss",
928            r#"
929#define ENGINE_NUM_STRUCTURES 2
930#define ENGINE_STRUCTURE_0 effect
931#define ENGINE_STRUCTURE_1 json
932
933json JSON_DYNAMIC = JsonParse("{\"enabled\":true}");
934void TestDefaults(
935    json jData = JsonParse("{}"),
936    effect eDamage = EffectDamage(5)
937);
938"#,
939        )
940        .expect("langspec should parse");
941
942        assert_eq!(
943            spec.constants
944                .iter()
945                .find(|constant| constant.name == "JSON_DYNAMIC")
946                .map(|constant| constant.value.clone()),
947            Some(BuiltinValue::Raw(
948                "JsonParse(\"{\\\"enabled\\\":true}\")".to_string()
949            ))
950        );
951
952        let defaults = spec
953            .functions
954            .iter()
955            .find(|function| function.name == "TestDefaults")
956            .expect("TestDefaults should exist")
957            .parameters
958            .iter()
959            .map(|parameter| parameter.default.clone())
960            .collect::<Vec<_>>();
961
962        assert_eq!(
963            defaults,
964            vec![
965                Some(BuiltinValue::Raw("JsonParse(\"{}\")".to_string())),
966                Some(BuiltinValue::Raw("EffectDamage(5)".to_string())),
967            ]
968        );
969    }
970}