1use std::cell::RefCell;
2use indexmap::IndexMap;
3use serde::Serialize;
4use crate::ast::doc_comment::DocComment;
5use crate::ast::decorator::Decorator;
6use crate::ast::field::Field;
7use crate::ast::handler::HandlerDeclaration;
8use crate::ast::identifier::Identifier;
9use crate::ast::span::Span;
10use crate::{declare_container_node, impl_container_node_defaults, node_child_fn, node_children_iter, node_children_iter_fn, node_optional_child_fn};
11use crate::ast::include_handler_from_template::IncludeHandlerFromTemplate;
12use crate::ast::partial_field::PartialField;
13use crate::format::Writer;
14use crate::r#type::synthesized_enum::SynthesizedEnum;
15use crate::r#type::synthesized_enum_reference::SynthesizedEnumReferenceKind;
16use crate::r#type::synthesized_interface_enum::SynthesizedInterfaceEnum;
17use crate::r#type::synthesized_interface_enum_reference::SynthesizedInterfaceEnumReferenceKind;
18use crate::r#type::synthesized_shape::SynthesizedShape;
19use crate::r#type::synthesized_shape_reference::SynthesizedShapeReferenceKind;
20use crate::r#type::Type;
21use crate::traits::info_provider::InfoProvider;
22use crate::traits::resolved::Resolve;
23use crate::traits::write::Write;
24
25declare_container_node!(Model, named, availability,
26 pub(crate) comment: Option<usize>,
27 pub(crate) identifier: usize,
28 pub(crate) fields: Vec<usize>,
29 pub(crate) partial_fields: Vec<usize>,
30 pub(crate) decorators: Vec<usize>,
31 pub(crate) empty_decorator_spans: Vec<Span>,
32 pub(crate) empty_field_decorator_spans: Vec<Span>,
33 pub(crate) unattached_field_decorators: Vec<Decorator>,
34 pub(crate) handlers: Vec<usize>,
35 pub(crate) handler_inclusions: Vec<usize>,
36 pub(crate) resolved: RefCell<Option<ModelResolved>>,
37);
38
39impl_container_node_defaults!(Model, named, availability);
40
41node_children_iter!(Model, Decorator, DecoratorsIter, decorators);
42
43node_children_iter!(Model, Field, FieldsIter, fields);
44
45node_children_iter!(Model, PartialField, PartialFieldsIter, partial_fields);
46
47node_children_iter!(Model, HandlerDeclaration, HandlersIter, handlers);
48
49node_children_iter!(Model, IncludeHandlerFromTemplate, HandlersInclusionIter, handler_inclusions);
50
51impl Model {
52
53 node_optional_child_fn!(comment, DocComment);
54
55 node_child_fn!(identifier, Identifier);
56
57 node_children_iter_fn!(decorators, DecoratorsIter);
58
59 node_children_iter_fn!(fields, FieldsIter);
60
61 node_children_iter_fn!(partial_fields, PartialFieldsIter);
62
63 node_children_iter_fn!(handlers, HandlersIter);
64
65 node_children_iter_fn!(handler_inclusions, HandlersInclusionIter);
66}
67
68#[derive(Debug, Serialize, Clone)]
69pub struct ModelResolved {
70 pub enums: IndexMap<SynthesizedEnumReferenceKind, SynthesizedEnum>,
71 pub interface_enums: IndexMap<SynthesizedInterfaceEnumReferenceKind, SynthesizedInterfaceEnum>,
72 pub shapes: IndexMap<(SynthesizedShapeReferenceKind, Option<String>), Type>,
73 pub declared_shapes: IndexMap<Vec<String>, SynthesizedShape>,
74}
75
76impl ModelResolved {
77
78 pub fn new() -> Self {
79 Self {
80 enums: Default::default(),
81 interface_enums: Default::default(),
82 shapes: Default::default(),
83 declared_shapes: Default::default(),
84 }
85 }
86
87 pub fn get(&self, key: SynthesizedShapeReferenceKind) -> Option<&Type> {
88 self.shapes.get(&(key, None))
89 }
90
91 pub fn get_without(&self, key: SynthesizedShapeReferenceKind, without: &str) -> Option<&Type> {
92 self.shapes.get(&(key, Some(without.to_owned())))
93 }
94
95 pub fn get_declared(&self, path: &Vec<String>) -> Option<&SynthesizedShape> {
96 self.declared_shapes.get(path)
97 }
98
99 pub fn set_declared(&mut self, path: Vec<String>, shape: SynthesizedShape) {
100 self.declared_shapes.insert(path, shape);
101 }
102}
103
104impl Resolve<ModelResolved> for Model {
105 fn resolved_ref_cell(&self) -> &RefCell<Option<ModelResolved>> {
106 &self.resolved
107 }
108}
109
110impl InfoProvider for Model {
111 fn namespace_skip(&self) -> usize {
112 1
113 }
114}
115
116impl Write for Model {
117 fn write<'a>(&'a self, writer: &mut Writer<'a>) {
118 writer.write_children(self, self.children.values());
119 }
120
121 fn is_block_level_element(&self) -> bool {
122 true
123 }
124}