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 forced_alignment: Option<(u32, Span)>,
267 pub deprecated: bool,
268 pub docstrings: Docstrings,
269}
270
271#[derive(Copy, Clone, Debug)]
272pub enum TableFieldTagKind {
274 None,
275 UnionTag,
276 UnionTagVector,
277}
278
279impl TableFieldTagKind {
280 pub fn size(self) -> u32 {
282 match self {
283 TableFieldTagKind::None => 0,
284 TableFieldTagKind::UnionTag => 1,
285 TableFieldTagKind::UnionTagVector => 4,
286 }
287 }
288}
289
290#[derive(Clone, Debug)]
291pub enum AssignMode {
292 Required,
293 Optional,
294 HasDefault(Literal),
295}
296
297#[derive(Debug)]
298pub struct Struct {
299 pub fields: IndexMap<String, StructField>,
300 pub size: u32,
301 pub alignment: u32,
302}
303
304#[derive(Debug)]
305pub struct StructField {
306 pub type_: SimpleType,
307 pub offset: u32,
308 pub size: u32,
309 pub padding_after_field: u32,
310 pub docstrings: Docstrings,
311}
312
313#[derive(Debug, Clone)]
314pub struct Enum {
315 pub type_: IntegerType,
316 pub variants: IndexMap<IntegerLiteral, EnumVariant>,
317 pub alignment: u32,
318}
319
320#[derive(Debug, Clone)]
321pub struct EnumVariant {
322 pub span: Span,
323 pub name: String,
324 pub docstrings: Docstrings,
325}
326
327#[derive(Debug)]
328pub struct Union {
329 pub variants: IndexMap<String, UnionVariant>,
330}
331
332#[derive(Debug)]
333pub struct UnionVariant {
334 pub type_: Type,
335 pub docstrings: Docstrings,
336}
337
338#[derive(Debug)]
339pub struct RpcService {
340 pub methods: IndexMap<String, RpcMethod>,
341}
342
343#[derive(Debug)]
344pub struct RpcMethod {
345 pub argument_type: Type,
346 pub return_type: Type,
347}
348
349#[derive(Debug, PartialEq, Eq, Hash)]
350pub struct Type {
351 pub span: Span,
352 pub kind: TypeKind,
353}
354
355impl TypeKind {
356 pub fn is_scalar(&self) -> bool {
357 match self {
358 TypeKind::Table(_)
359 | TypeKind::Union(_)
360 | TypeKind::Vector(_)
361 | TypeKind::Array(_, _)
362 | TypeKind::String => false,
363 TypeKind::SimpleType(type_) => type_.is_scalar(),
364 }
365 }
366
367 pub fn is_enum(&self) -> bool {
368 matches!(self, &TypeKind::SimpleType(SimpleType::Enum(..)))
369 }
370
371 pub fn is_type_with_tag(&self) -> bool {
372 match self {
373 TypeKind::Union(_) => true,
374 TypeKind::Vector(inner) => matches!(inner.kind, TypeKind::Union(_)),
375 _ => false,
376 }
377 }
378
379 fn add_children(&self, children: &mut BTreeSet<DeclarationIndex>) {
380 match self {
381 TypeKind::Table(decl_id) | TypeKind::Union(decl_id) => {
382 children.insert(*decl_id);
383 }
384 TypeKind::Vector(type_) | TypeKind::Array(type_, _) => {
385 type_.kind.add_children(children)
386 }
387 TypeKind::SimpleType(kind) => {
388 kind.add_children(children);
389 }
390 TypeKind::String => (),
391 }
392 }
393}
394
395#[derive(Debug, PartialEq, Eq, Hash)]
396pub enum TypeKind {
397 Table(DeclarationIndex),
398 Union(DeclarationIndex),
399 Vector(Box<Type>),
400 Array(Box<Type>, u32),
401 SimpleType(SimpleType),
402 String,
403}
404
405#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
406pub enum SimpleType {
407 Struct(DeclarationIndex),
408 Enum(DeclarationIndex),
409 Bool,
410 Integer(IntegerType),
411 Float(FloatType),
412}
413
414impl SimpleType {
415 pub fn is_scalar(&self) -> bool {
416 match self {
417 SimpleType::Struct(_) => false,
418 SimpleType::Enum(_)
419 | SimpleType::Bool
420 | SimpleType::Integer(_)
421 | SimpleType::Float(_) => true,
422 }
423 }
424
425 fn add_children(&self, children: &mut BTreeSet<DeclarationIndex>) {
426 match self {
427 SimpleType::Struct(decl_id) | SimpleType::Enum(decl_id) => {
428 children.insert(*decl_id);
429 }
430 SimpleType::Bool | SimpleType::Integer(_) | SimpleType::Float(_) => (),
431 }
432 }
433}
434
435#[derive(Clone, Debug)]
436pub enum Literal {
437 Bool(bool),
438 String(String),
439 Int(IntegerLiteral),
440 Float(FloatLiteral),
441 Array(Vec<Literal>),
442 Vector(Vec<Literal>),
443 EnumTag {
444 variant_index: usize,
445 value: IntegerLiteral,
446 },
447}
448
449#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
450pub enum IntegerLiteral {
451 U8(u8),
452 I8(i8),
453 U16(u16),
454 I16(i16),
455 U32(u32),
456 I32(i32),
457 U64(u64),
458 I64(i64),
459}
460
461impl IntegerLiteral {
462 pub fn is_zero(&self) -> bool {
463 match self {
464 IntegerLiteral::U8(n) => *n == 0,
465 IntegerLiteral::I8(n) => *n == 0,
466 IntegerLiteral::U16(n) => *n == 0,
467 IntegerLiteral::I16(n) => *n == 0,
468 IntegerLiteral::U32(n) => *n == 0,
469 IntegerLiteral::I32(n) => *n == 0,
470 IntegerLiteral::U64(n) => *n == 0,
471 IntegerLiteral::I64(n) => *n == 0,
472 }
473 }
474
475 pub fn to_u64(&self) -> u64 {
476 match self {
477 IntegerLiteral::U8(v) => *v as u64,
478 IntegerLiteral::I8(v) => *v as u64,
479 IntegerLiteral::U16(v) => *v as u64,
480 IntegerLiteral::I16(v) => *v as u64,
481 IntegerLiteral::U32(v) => *v as u64,
482 IntegerLiteral::I32(v) => *v as u64,
483 IntegerLiteral::U64(v) => *v,
484 IntegerLiteral::I64(v) => *v as u64,
485 }
486 }
487}
488
489impl Display for Literal {
490 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
491 match self {
492 Literal::Bool(v) => write!(f, "{v}"),
493 Literal::String(v) => write!(f, "{v}"),
494 Literal::Int(v) => write!(f, "{v}"),
495 Literal::Float(v) => write!(f, "{v}"),
496 Literal::Array(vs) | Literal::Vector(vs) => {
497 write!(f, "[")?;
498 let mut first = true;
499 for v in vs {
500 if !first {
501 write!(f, ", {v}")?;
502 } else {
503 first = false;
504 write!(f, "{v}")?;
505 }
506 }
507 write!(f, "]")
508 }
509 Literal::EnumTag { value, .. } => write!(f, "{value}"),
510 }
511 }
512}
513
514impl Display for IntegerLiteral {
515 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
516 match self {
517 IntegerLiteral::U8(v) => write!(f, "{v}"),
518 IntegerLiteral::I8(v) => write!(f, "{v}"),
519 IntegerLiteral::U16(v) => write!(f, "{v}"),
520 IntegerLiteral::I16(v) => write!(f, "{v}"),
521 IntegerLiteral::U32(v) => write!(f, "{v}"),
522 IntegerLiteral::I32(v) => write!(f, "{v}"),
523 IntegerLiteral::U64(v) => write!(f, "{v}"),
524 IntegerLiteral::I64(v) => write!(f, "{v}"),
525 }
526 }
527}
528
529#[derive(Copy, Clone, Debug)]
530pub enum FloatLiteral {
531 F32(f32),
532 F64(f64),
533}
534
535impl Display for FloatLiteral {
536 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
537 match self {
538 FloatLiteral::F32(v) => write!(f, "{v:?}"),
539 FloatLiteral::F64(v) => write!(f, "{v:?}"),
540 }
541 }
542}
543impl Table {
544 fn children(&self) -> Vec<DeclarationIndex> {
545 let mut children = BTreeSet::new();
546 for field in self.fields.values() {
547 field.type_.kind.add_children(&mut children);
548 }
549 children.into_iter().collect()
550 }
551
552 pub fn get_field_for_vtable_index(
553 &self,
554 vtable_index: u32,
555 ) -> Option<(&str, &TableField, bool)> {
556 for (field_name, field) in &self.fields {
557 if vtable_index == field.vtable_index {
558 return Some((field_name, field, field.type_.kind.is_type_with_tag()));
559 }
560 if vtable_index == field.vtable_index + 1 && field.type_.kind.is_type_with_tag() {
561 return Some((field_name, field, false));
562 }
563 }
564 None
565 }
566}
567
568impl Struct {
569 fn children(&self) -> Vec<DeclarationIndex> {
570 let mut children = BTreeSet::new();
571 for field in self.fields.values() {
572 field.type_.add_children(&mut children);
573 }
574 children.into_iter().collect()
575 }
576}
577
578impl Union {
579 fn children(&self) -> Vec<DeclarationIndex> {
580 let mut children = BTreeSet::new();
581 for variant in self.variants.values() {
582 variant.type_.kind.add_children(&mut children);
583 }
584 children.into_iter().collect()
585 }
586}
587
588impl RpcService {
589 fn children(&self) -> Vec<DeclarationIndex> {
590 let mut children = BTreeSet::new();
591 for method in self.methods.values() {
592 method.argument_type.kind.add_children(&mut children);
593 method.return_type.kind.add_children(&mut children);
594 }
595 children.into_iter().collect()
596 }
597}
598
599impl IntegerLiteral {
600 pub fn default_value_from_type(type_: &crate::ast::IntegerType) -> Self {
601 match type_ {
602 crate::ast::IntegerType::U8 => Self::U8(0),
603 crate::ast::IntegerType::U16 => Self::U16(0),
604 crate::ast::IntegerType::U32 => Self::U32(0),
605 crate::ast::IntegerType::U64 => Self::U64(0),
606 crate::ast::IntegerType::I8 => Self::I8(0),
607 crate::ast::IntegerType::I16 => Self::I16(0),
608 crate::ast::IntegerType::I32 => Self::I32(0),
609 crate::ast::IntegerType::I64 => Self::I64(0),
610 }
611 }
612
613 #[must_use]
614 pub fn next(&self) -> Self {
615 match self {
616 Self::U8(n) => Self::U8(n.wrapping_add(1)),
617 Self::I8(n) => Self::I8(n.wrapping_add(1)),
618 Self::U16(n) => Self::U16(n.wrapping_add(1)),
619 Self::I16(n) => Self::I16(n.wrapping_add(1)),
620 Self::U32(n) => Self::U32(n.wrapping_add(1)),
621 Self::I32(n) => Self::I32(n.wrapping_add(1)),
622 Self::U64(n) => Self::U64(n.wrapping_add(1)),
623 Self::I64(n) => Self::I64(n.wrapping_add(1)),
624 }
625 }
626}
627
628impl From<&crate::ast::BuiltinType> for TypeKind {
629 fn from(value: &crate::ast::BuiltinType) -> TypeKind {
630 match value {
631 crate::ast::BuiltinType::Bool => TypeKind::SimpleType(SimpleType::Bool),
632 crate::ast::BuiltinType::Integer(typ) => {
633 TypeKind::SimpleType(SimpleType::Integer(*typ))
634 }
635 crate::ast::BuiltinType::Float(typ) => TypeKind::SimpleType(SimpleType::Float(*typ)),
636 crate::ast::BuiltinType::String => TypeKind::String,
637 }
638 }
639}