1use std::{borrow::Cow, collections::BTreeSet, fmt::Display};
2
3use codespan::{FileId, Span};
4use indexmap::IndexMap;
5
6use crate::ast::{Docstrings, FloatType, IntegerType};
7
8#[derive(Clone, Hash, PartialEq, Eq, Debug)]
9pub struct AbsolutePath(pub Vec<String>);
10
11impl AbsolutePath {
12 pub const ROOT_PATH: Self = Self(Vec::new());
13
14 pub fn push<S: Into<String>>(&mut self, value: S) {
15 self.0.push(value.into())
16 }
17
18 pub fn pop(&mut self) -> Option<String> {
19 self.0.pop()
20 }
21
22 #[must_use]
23 pub fn clone_push<S: AsRef<str>>(&self, value: S) -> Self {
24 let mut r = self.clone();
25 r.push(value.as_ref());
26 r
27 }
28
29 #[must_use]
30 pub fn clone_pop(&self) -> Self {
31 assert!(!self.0.is_empty());
32 Self(self.0[..self.0.len() - 1].to_vec())
33 }
34}
35
36impl std::fmt::Display for AbsolutePath {
37 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
38 let mut first = true;
39 for part in &self.0 {
40 if first {
41 first = false;
42 write!(f, "{part}")?;
43 } else {
44 write!(f, ".{part}")?;
45 }
46 }
47 Ok(())
48 }
49}
50
51pub struct RelativePath {
52 pub count_until_shared_parent: usize,
53 pub remaining: Vec<String>,
54}
55
56#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
57pub struct DeclarationIndex(pub usize);
58impl DeclarationIndex {
59 pub const INVALID: DeclarationIndex = DeclarationIndex(usize::MAX);
60}
61
62impl Display for DeclarationIndex {
63 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
64 write!(f, "{}", self.0)
65 }
66}
67
68impl<'a> From<&'a DeclarationIndex> for DeclarationIndex {
69 fn from(decl: &'a DeclarationIndex) -> Self {
70 *decl
71 }
72}
73
74impl<'a, 'b> From<&'b &'a DeclarationIndex> for DeclarationIndex {
75 fn from(decl: &'b &'a DeclarationIndex) -> Self {
76 **decl
77 }
78}
79
80#[derive(Copy, Clone, Debug)]
81pub struct NamespaceIndex(pub usize);
82impl NamespaceIndex {
83 pub const INVALID: NamespaceIndex = NamespaceIndex(usize::MAX);
84}
85
86impl<'a> From<&'a NamespaceIndex> for NamespaceIndex {
87 fn from(namespace: &'a NamespaceIndex) -> Self {
88 *namespace
89 }
90}
91
92impl<'a, 'b> From<&'b &'a NamespaceIndex> for NamespaceIndex {
93 fn from(namespace: &'b &'a NamespaceIndex) -> Self {
94 **namespace
95 }
96}
97
98#[derive(Debug)]
99pub struct Declarations {
100 pub namespaces: IndexMap<AbsolutePath, Namespace>,
101 pub declarations: IndexMap<AbsolutePath, Declaration>,
102 pub children: Vec<Vec<DeclarationIndex>>,
103 pub parents: Vec<Vec<DeclarationIndex>>,
104}
105
106impl Declarations {
107 pub fn new(
108 namespaces: IndexMap<AbsolutePath, Namespace>,
109 declarations: IndexMap<AbsolutePath, Declaration>,
110 ) -> Self {
111 let children = declarations
112 .values()
113 .map(|decl| match &decl.kind {
114 DeclarationKind::Table(decl) => decl.children(),
115 DeclarationKind::Struct(decl) => decl.children(),
116 DeclarationKind::Enum(_) => Vec::new(),
117 DeclarationKind::Union(decl) => decl.children(),
118 DeclarationKind::RpcService(decl) => decl.children(),
119 })
120 .collect::<Vec<_>>();
121
122 let mut parents = (0..declarations.len())
123 .map(|_| Vec::new())
124 .collect::<Vec<_>>();
125 for (parent_decl_id, children) in children.iter().enumerate() {
126 for child_decl_id in children {
127 parents[child_decl_id.0].push(DeclarationIndex(parent_decl_id));
128 }
129 }
130
131 Self {
132 namespaces,
133 declarations,
134 children,
135 parents,
136 }
137 }
138
139 pub fn get_namespace(&self, index: NamespaceIndex) -> (&AbsolutePath, &Namespace) {
140 self.namespaces.get_index(index.0).unwrap()
141 }
142
143 pub fn get_root_namespace(&self) -> (NamespaceIndex, &Namespace) {
144 let (index, _, namespace) = self.namespaces.get_full(&AbsolutePath::ROOT_PATH).unwrap();
145 (NamespaceIndex(index), namespace)
146 }
147
148 pub fn get_declaration(&self, index: DeclarationIndex) -> (&AbsolutePath, &Declaration) {
149 self.declarations.get_index(index.0).unwrap()
150 }
151
152 pub fn iter_declarations(
153 &self,
154 ) -> impl Iterator<Item = (DeclarationIndex, &AbsolutePath, &Declaration)> {
155 self.declarations
156 .iter()
157 .enumerate()
158 .map(|(i, (k, v))| (DeclarationIndex(i), k, v))
159 }
160
161 pub fn format_type_kind(&self, type_: &TypeKind) -> Cow<'static, str> {
162 match type_ {
163 TypeKind::Table(index) => {
164 Cow::Owned(format!("table {}", self.get_declaration(*index).0))
165 }
166 TypeKind::Union(index) => {
167 Cow::Owned(format!("union {}", self.get_declaration(*index).0))
168 }
169 TypeKind::Vector(type_) => {
170 Cow::Owned(format!("[{}]", self.format_type_kind(&type_.kind)))
171 }
172 TypeKind::Array(type_, size) => {
173 Cow::Owned(format!("[{}; {size}]", self.format_type_kind(&type_.kind)))
174 }
175 TypeKind::SimpleType(type_) => self.format_simple_type(type_),
176 TypeKind::String => Cow::Borrowed("string"),
177 }
178 }
179
180 pub fn format_simple_type(&self, type_: &SimpleType) -> Cow<'static, str> {
181 match type_ {
182 SimpleType::Struct(index) => {
183 Cow::Owned(format!("struct {}", self.get_declaration(*index).0))
184 }
185 SimpleType::Enum(index) => {
186 Cow::Owned(format!("enum {}", self.get_declaration(*index).0))
187 }
188 SimpleType::Bool => Cow::Borrowed("bool"),
189 SimpleType::Integer(type_) => Cow::Borrowed(type_.flatbuffer_name()),
190 SimpleType::Float(type_) => Cow::Borrowed(type_.flatbuffer_name()),
191 }
192 }
193}
194
195#[derive(Debug)]
196pub struct Namespace {
197 pub spans: Vec<(FileId, Option<Span>)>,
199 pub docstrings: Docstrings,
200 pub child_namespaces: IndexMap<String, NamespaceIndex>,
201 pub declaration_ids: IndexMap<String, DeclarationIndex>,
202}
203
204impl Default for Namespace {
205 fn default() -> Self {
206 Self {
207 spans: Default::default(),
208 docstrings: Docstrings::new(None),
209 child_namespaces: Default::default(),
210 declaration_ids: Default::default(),
211 }
212 }
213}
214
215#[derive(Debug)]
216pub struct Declaration {
217 pub definition_span: Span,
218 pub file_id: FileId,
219 pub namespace_id: NamespaceIndex,
220 pub kind: DeclarationKind,
221 pub docstrings: Docstrings,
222}
223
224#[derive(Debug)]
225pub enum DeclarationKind {
226 Table(Table),
227 Struct(Struct),
228 Enum(Enum),
229 Union(Union),
230 RpcService(RpcService),
231}
232
233impl DeclarationKind {
234 pub fn kind_as_str(&self) -> &'static str {
235 match self {
236 DeclarationKind::Table(_) => "table",
237 DeclarationKind::Struct(_) => "struct",
238 DeclarationKind::Enum(_) => "enum",
239 DeclarationKind::Union(_) => "union",
240 DeclarationKind::RpcService(_) => "rpc_service",
241 }
242 }
243}
244
245#[derive(Debug)]
246pub struct Table {
247 pub fields: IndexMap<String, TableField>,
248 pub alignment_order: Vec<usize>,
249 pub max_size: u32,
250 pub max_vtable_size: u32,
251 pub max_alignment: u32,
252}
253
254#[derive(Debug)]
255pub struct TableField {
256 pub vtable_index: u32,
259 pub span: Span,
260 pub type_: Type,
261 pub assign_mode: AssignMode,
262 pub object_value_size: u32,
263 pub object_tag_kind: TableFieldTagKind,
264 pub object_alignment_mask: u32,
265 pub object_alignment: u32,
266 pub deprecated: bool,
267 pub docstrings: Docstrings,
268}
269
270#[derive(Copy, Clone, Debug)]
271pub enum TableFieldTagKind {
273 None,
274 UnionTag,
275 UnionTagVector,
276}
277
278impl TableFieldTagKind {
279 pub fn size(self) -> u32 {
281 match self {
282 TableFieldTagKind::None => 0,
283 TableFieldTagKind::UnionTag => 1,
284 TableFieldTagKind::UnionTagVector => 4,
285 }
286 }
287}
288
289#[derive(Clone, Debug)]
290pub enum AssignMode {
291 Required,
292 Optional,
293 HasDefault(Literal),
294}
295
296#[derive(Debug)]
297pub struct Struct {
298 pub fields: IndexMap<String, StructField>,
299 pub size: u32,
300 pub alignment: u32,
301}
302
303#[derive(Debug)]
304pub struct StructField {
305 pub type_: SimpleType,
306 pub offset: u32,
307 pub size: u32,
308 pub padding_after_field: u32,
309 pub docstrings: Docstrings,
310}
311
312#[derive(Debug, Clone)]
313pub struct Enum {
314 pub type_: IntegerType,
315 pub variants: IndexMap<IntegerLiteral, EnumVariant>,
316 pub alignment: u32,
317}
318
319#[derive(Debug, Clone)]
320pub struct EnumVariant {
321 pub span: Span,
322 pub name: String,
323 pub docstrings: Docstrings,
324}
325
326#[derive(Debug)]
327pub struct Union {
328 pub variants: IndexMap<String, UnionVariant>,
329}
330
331#[derive(Debug)]
332pub struct UnionVariant {
333 pub type_: Type,
334 pub docstrings: Docstrings,
335}
336
337#[derive(Debug)]
338pub struct RpcService {
339 pub methods: IndexMap<String, RpcMethod>,
340}
341
342#[derive(Debug)]
343pub struct RpcMethod {
344 pub argument_type: Type,
345 pub return_type: Type,
346}
347
348#[derive(Debug, PartialEq, Eq, Hash)]
349pub struct Type {
350 pub span: Span,
351 pub kind: TypeKind,
352}
353
354impl TypeKind {
355 pub fn is_scalar(&self) -> bool {
356 match self {
357 TypeKind::Table(_)
358 | TypeKind::Union(_)
359 | TypeKind::Vector(_)
360 | TypeKind::Array(_, _)
361 | TypeKind::String => false,
362 TypeKind::SimpleType(type_) => type_.is_scalar(),
363 }
364 }
365
366 pub fn is_enum(&self) -> bool {
367 matches!(self, &TypeKind::SimpleType(SimpleType::Enum(..)))
368 }
369
370 pub fn is_type_with_tag(&self) -> bool {
371 match self {
372 TypeKind::Union(_) => true,
373 TypeKind::Vector(inner) => matches!(inner.kind, TypeKind::Union(_)),
374 _ => false,
375 }
376 }
377
378 fn add_children(&self, children: &mut BTreeSet<DeclarationIndex>) {
379 match self {
380 TypeKind::Table(decl_id) | TypeKind::Union(decl_id) => {
381 children.insert(*decl_id);
382 }
383 TypeKind::Vector(type_) | TypeKind::Array(type_, _) => {
384 type_.kind.add_children(children)
385 }
386 TypeKind::SimpleType(kind) => {
387 kind.add_children(children);
388 }
389 TypeKind::String => (),
390 }
391 }
392}
393
394#[derive(Debug, PartialEq, Eq, Hash)]
395pub enum TypeKind {
396 Table(DeclarationIndex),
397 Union(DeclarationIndex),
398 Vector(Box<Type>),
399 Array(Box<Type>, u32),
400 SimpleType(SimpleType),
401 String,
402}
403
404#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
405pub enum SimpleType {
406 Struct(DeclarationIndex),
407 Enum(DeclarationIndex),
408 Bool,
409 Integer(IntegerType),
410 Float(FloatType),
411}
412
413impl SimpleType {
414 pub fn is_scalar(&self) -> bool {
415 match self {
416 SimpleType::Struct(_) => false,
417 SimpleType::Enum(_)
418 | SimpleType::Bool
419 | SimpleType::Integer(_)
420 | SimpleType::Float(_) => true,
421 }
422 }
423
424 fn add_children(&self, children: &mut BTreeSet<DeclarationIndex>) {
425 match self {
426 SimpleType::Struct(decl_id) | SimpleType::Enum(decl_id) => {
427 children.insert(*decl_id);
428 }
429 SimpleType::Bool | SimpleType::Integer(_) | SimpleType::Float(_) => (),
430 }
431 }
432}
433
434#[derive(Clone, Debug)]
435pub enum Literal {
436 Bool(bool),
437 String(String),
438 Int(IntegerLiteral),
439 Float(FloatLiteral),
440 Array(Vec<Literal>),
441 Vector(Vec<Literal>),
442 EnumTag {
443 variant_index: usize,
444 value: IntegerLiteral,
445 },
446}
447
448#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
449pub enum IntegerLiteral {
450 U8(u8),
451 I8(i8),
452 U16(u16),
453 I16(i16),
454 U32(u32),
455 I32(i32),
456 U64(u64),
457 I64(i64),
458}
459
460impl IntegerLiteral {
461 pub fn is_zero(&self) -> bool {
462 match self {
463 IntegerLiteral::U8(n) => *n == 0,
464 IntegerLiteral::I8(n) => *n == 0,
465 IntegerLiteral::U16(n) => *n == 0,
466 IntegerLiteral::I16(n) => *n == 0,
467 IntegerLiteral::U32(n) => *n == 0,
468 IntegerLiteral::I32(n) => *n == 0,
469 IntegerLiteral::U64(n) => *n == 0,
470 IntegerLiteral::I64(n) => *n == 0,
471 }
472 }
473
474 pub fn to_u64(&self) -> u64 {
475 match self {
476 IntegerLiteral::U8(v) => *v as u64,
477 IntegerLiteral::I8(v) => *v as u64,
478 IntegerLiteral::U16(v) => *v as u64,
479 IntegerLiteral::I16(v) => *v as u64,
480 IntegerLiteral::U32(v) => *v as u64,
481 IntegerLiteral::I32(v) => *v as u64,
482 IntegerLiteral::U64(v) => *v,
483 IntegerLiteral::I64(v) => *v as u64,
484 }
485 }
486}
487
488impl Display for Literal {
489 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
490 match self {
491 Literal::Bool(v) => write!(f, "{v}"),
492 Literal::String(v) => write!(f, "{v}"),
493 Literal::Int(v) => write!(f, "{v}"),
494 Literal::Float(v) => write!(f, "{v}"),
495 Literal::Array(vs) | Literal::Vector(vs) => {
496 write!(f, "[")?;
497 let mut first = true;
498 for v in vs {
499 if !first {
500 write!(f, ", {v}")?;
501 } else {
502 first = false;
503 write!(f, "{v}")?;
504 }
505 }
506 write!(f, "]")
507 }
508 Literal::EnumTag { value, .. } => write!(f, "{value}"),
509 }
510 }
511}
512
513impl Display for IntegerLiteral {
514 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
515 match self {
516 IntegerLiteral::U8(v) => write!(f, "{v}"),
517 IntegerLiteral::I8(v) => write!(f, "{v}"),
518 IntegerLiteral::U16(v) => write!(f, "{v}"),
519 IntegerLiteral::I16(v) => write!(f, "{v}"),
520 IntegerLiteral::U32(v) => write!(f, "{v}"),
521 IntegerLiteral::I32(v) => write!(f, "{v}"),
522 IntegerLiteral::U64(v) => write!(f, "{v}"),
523 IntegerLiteral::I64(v) => write!(f, "{v}"),
524 }
525 }
526}
527
528#[derive(Copy, Clone, Debug)]
529pub enum FloatLiteral {
530 F32(f32),
531 F64(f64),
532}
533
534impl Display for FloatLiteral {
535 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
536 match self {
537 FloatLiteral::F32(v) => write!(f, "{v:?}"),
538 FloatLiteral::F64(v) => write!(f, "{v:?}"),
539 }
540 }
541}
542impl Table {
543 fn children(&self) -> Vec<DeclarationIndex> {
544 let mut children = BTreeSet::new();
545 for field in self.fields.values() {
546 field.type_.kind.add_children(&mut children);
547 }
548 children.into_iter().collect()
549 }
550
551 pub fn get_field_for_vtable_index(
552 &self,
553 vtable_index: u32,
554 ) -> Option<(&str, &TableField, bool)> {
555 for (field_name, field) in &self.fields {
556 if vtable_index == field.vtable_index {
557 return Some((field_name, field, field.type_.kind.is_type_with_tag()));
558 }
559 if vtable_index == field.vtable_index + 1 && field.type_.kind.is_type_with_tag() {
560 return Some((field_name, field, false));
561 }
562 }
563 None
564 }
565}
566
567impl Struct {
568 fn children(&self) -> Vec<DeclarationIndex> {
569 let mut children = BTreeSet::new();
570 for field in self.fields.values() {
571 field.type_.add_children(&mut children);
572 }
573 children.into_iter().collect()
574 }
575}
576
577impl Union {
578 fn children(&self) -> Vec<DeclarationIndex> {
579 let mut children = BTreeSet::new();
580 for variant in self.variants.values() {
581 variant.type_.kind.add_children(&mut children);
582 }
583 children.into_iter().collect()
584 }
585}
586
587impl RpcService {
588 fn children(&self) -> Vec<DeclarationIndex> {
589 let mut children = BTreeSet::new();
590 for method in self.methods.values() {
591 method.argument_type.kind.add_children(&mut children);
592 method.return_type.kind.add_children(&mut children);
593 }
594 children.into_iter().collect()
595 }
596}
597
598impl IntegerLiteral {
599 pub fn default_value_from_type(type_: &crate::ast::IntegerType) -> Self {
600 match type_ {
601 crate::ast::IntegerType::U8 => Self::U8(0),
602 crate::ast::IntegerType::U16 => Self::U16(0),
603 crate::ast::IntegerType::U32 => Self::U32(0),
604 crate::ast::IntegerType::U64 => Self::U64(0),
605 crate::ast::IntegerType::I8 => Self::I8(0),
606 crate::ast::IntegerType::I16 => Self::I16(0),
607 crate::ast::IntegerType::I32 => Self::I32(0),
608 crate::ast::IntegerType::I64 => Self::I64(0),
609 }
610 }
611
612 #[must_use]
613 pub fn next(&self) -> Self {
614 match self {
615 Self::U8(n) => Self::U8(n.wrapping_add(1)),
616 Self::I8(n) => Self::I8(n.wrapping_add(1)),
617 Self::U16(n) => Self::U16(n.wrapping_add(1)),
618 Self::I16(n) => Self::I16(n.wrapping_add(1)),
619 Self::U32(n) => Self::U32(n.wrapping_add(1)),
620 Self::I32(n) => Self::I32(n.wrapping_add(1)),
621 Self::U64(n) => Self::U64(n.wrapping_add(1)),
622 Self::I64(n) => Self::I64(n.wrapping_add(1)),
623 }
624 }
625}
626
627impl From<&crate::ast::BuiltinType> for TypeKind {
628 fn from(value: &crate::ast::BuiltinType) -> TypeKind {
629 match value {
630 crate::ast::BuiltinType::Bool => TypeKind::SimpleType(SimpleType::Bool),
631 crate::ast::BuiltinType::Integer(typ) => {
632 TypeKind::SimpleType(SimpleType::Integer(*typ))
633 }
634 crate::ast::BuiltinType::Float(typ) => TypeKind::SimpleType(SimpleType::Float(*typ)),
635 crate::ast::BuiltinType::String => TypeKind::String,
636 }
637 }
638}