@startuml current

!theme vibrant

title Current Wasot Compiler - Overview

package "Core Data Structures" as core_data {
    class QuotedString <<struct>> {
        + content: String
        + quoted: bool
    }
    
    class Id <<struct>> {
        + value: String
        + new(value: String): Id
        + empty(): Id
        + is_empty(): bool
        + as_str(): &str
    }
    
    class MetaLine <<struct>> {
        + type_name: String
        + inline_text: QuotedString
        + raw_params: String
        + level: usize
        + id: Id
        + parse(line: &str): Option<MetaLine>
    }
    
    class ParsedParams <<struct>> {
        + args: Vec<QuotedString>
        + kwargs: Vec<(QuotedString, QuotedString)>
    }
    
    class Block <<struct>> {
        + block_type: String
        + level: usize
        + inline_text: QuotedString
        + params: ParsedParams
        + content: Vec<String>
        + children: Vec<Block>
        + parent_index: Option<usize>
        + id: Id
        --
        + new(meta_line: MetaLine, params: ParsedParams): Block
        + new_implicit_text(): Block
        + new_heading(meta_line: MetaLine, params: ParsedParams): Block
        + add_content_line(line: String)
        + add_child(child: Block, child_index: usize)
        + is_heading(): bool
        + is_implicit_text(): bool
        + can_contain_level(child_level: usize): bool
        + to_json(): Result<String, serde_json::Error>
        + to_json_pretty(): Result<String, serde_json::Error>
        + from_json(json: &str): Result<Block, serde_json::Error>
    }
    
    class BlockContainer <<struct>> {
        - blocks: Vec<Block>
        - root_indices: Vec<usize>
        --
        + new(): BlockContainer
        + add_block(block: Block): usize
        + get_block(index: usize): Option<&Block>
        + get_block_mut(index: usize): Option<&mut Block>
        + root_blocks(): Vec<&Block>
        + get_parent(index: usize): Option<&Block>
        + get_children(index: usize): Vec<&Block>
        + len(): usize
        + is_empty(): bool
        + to_json(): Result<String, serde_json::Error>
        + to_json_pretty(): Result<String, serde_json::Error>
        + from_json(json: &str): Result<BlockContainer, serde_json::Error>
    }
}

package "Events System" as events {
    enum BlockEvent <<enum>> {
        BlockStarted
        BlockFinished
        --
        Contains: block: Block
        Contains: depth: usize
        Contains: block_index: Option<usize>
    }
    
    interface BlockEventListener <<trait>> {
        + on_block_event(event: &BlockEvent)
    }
    
    class BlockEventPublisher <<struct>> {
        - listeners: Arc<Mutex<HashMap<u64, BoxedListener>>>
        - next_id: Arc<Mutex<u64>>
        --
        + new(): BlockEventPublisher
        + subscribe(listener: BoxedListener): u64
        + unsubscribe(listener_id: u64): bool
        + publish(event: &BlockEvent)
        + listener_count(): usize
        + clear_listeners()
    }
    
    class BlockStartListener<F> <<struct>> {
        - callback: F
        + new(callback: F): BlockStartListener<F>
    }
    
    class BlockFinishListener<F> <<struct>> {
        - callback: F
        + new(callback: F): BlockFinishListener<F>
    }
    
    class BlockLifecycleListener<S, F> <<struct>> {
        - on_start: S
        - on_finish: F
        + new(on_start: S, on_finish: F): BlockLifecycleListener<S, F>
    }
}

package "Parsing Core" as parsing {
    class BlockParser <<struct>> {
        - block_stack: Vec<Block>
        - container: BlockContainer
        - event_publisher: BlockEventPublisher
        - current_text_block: Option<Block>
        --
        + new(): BlockParser
        + with_event_publisher(event_publisher: BlockEventPublisher): BlockParser
        + event_publisher(): &BlockEventPublisher
        + current_depth(): usize
        + process_line(line: &str): Result<(), String>
        + finish(): Result<(), String>
        + into_container(): Result<BlockContainer, String>
        + container(): &BlockContainer
        + block_stack(): &[Block]
        + has_open_blocks(): bool
    }
    
    class DocumentParser <<struct>> {
        - block_parser: BlockParser
        --
        + new(): DocumentParser
        + with_event_publisher(event_publisher: BlockEventPublisher): DocumentParser
        + event_publisher(): &BlockEventPublisher
        + subscribe(listener: BoxedListener): u64
        + unsubscribe(listener_id: u64): bool
        + parse_file<P: AsRef<Path>>(file_path: P): io::Result<BlockContainer>
        + parse_reader<R: Read>(reader: R): io::Result<BlockContainer>
        + parse_string(content: &str): Result<BlockContainer, String>
        + current_depth(): usize
        + has_open_blocks(): bool
        + block_stack(): &[Block]
        + reset()
    }
}

package "Tokenization & Parameters" as tokenization {
    class QuotedText <<struct>> {
        + content: String
        + was_quoted: bool
        --
        + new(content: String, was_quoted: bool): QuotedText
        + quoted(content: String): QuotedText
        + unquoted(content: String): QuotedText
        + as_str(): &str
    }
    
    class QuotedToken <<struct>> {
        + content: String
        + was_quoted: bool
    }
    
    class TokenizerModule <<module>> {
        + tokenize_with_equals(input: &str): Vec<String>
        + tokenize_with_equals_and_quotes(input: &str): Vec<(String, bool, bool)>
        + find_first_equals_outside_quotes(token: &str): Option<usize>
    }
    
    class SimpleTokenizerModule <<module>> {
        + tokenize_params(input: &str): Vec<QuotedText>
    }
    
    class QuoteAwareTokenizerModule <<module>> {
        + tokenize_with_quotes(input: &str): Vec<QuotedToken>
        + parse_key_value_token(token: &QuotedToken, original_input: &str): (QuotedText, Option<QuotedText>)
    }
    
    class ParamsModule <<module>> {
        + parse_params(input: &str): ParsedParams
        - process_escapes(s: &str): String
        - find_quoted_segments(input: &str): Vec<(usize, usize, String)>
        - was_token_quoted(input: &str, token: &str): bool
    }
    
    class ParserModule <<module>> {
        + is_meta_line(line: &str): bool
        + split_into_parts(text: &str): Vec<String>
        + split_into_parts_and_trim(text: &str): Vec<String>
        + extract_line_type(text: &str): (String, String)
        - extract_id_string(input: &str): (String, String)
        - is_quoted_text(text: &str): bool
    }
}

package "Output & Conversion" as output {
    class XmlConverter<W: Write> <<struct>> {
        - writer: EventWriter<W>
        - element_stack: Vec<String>
        - indent_level: usize
        - pretty_print: bool
        --
        + new(writer: W, pretty_print: bool): Result<XmlConverter<W>, xml::writer::Error>
        + finish(): Result<W, xml::writer::Error>
        - create_block_attributes(block: &Block): Vec<(String, String)>
        - write_indent(): Result<(), xml::writer::Error>
        - start_element(block: &Block): Result<(), xml::writer::Error>
        - write_block_immediate_content(block: &Block): Result<(), xml::writer::Error>
        - write_element_with_text(element_name: &str, text_content: &str): Result<(), xml::writer::Error>
        - write_kwarg_element(key: &str, value: &str): Result<(), xml::writer::Error>
        - end_element(block: &Block): Result<(), xml::writer::Error>
    }
    
    class XmlConverterCapture <<struct>> {
        - xml_converter: XmlConverter<SharedWriter>
        + new(output: Arc<Mutex<Vec<u8>>>, pretty_print: bool): Result<XmlConverterCapture, xml::writer::Error>
    }
    
    class SharedWriter <<struct>> {
        - output: Arc<Mutex<Vec<u8>>>
        + new(output: Arc<Mutex<Vec<u8>>>): SharedWriter
    }
    
    class JsonLinesExporter <<struct>> {
        - writer: BufWriter<File>
        - current_depth: usize
        --
        + new<P: AsRef<Path>>(path: P): Result<JsonLinesExporter, std::io::Error>
        + finish(): Result<(), std::io::Error>
        - write_block(block: &Block): Result<(), Box<dyn std::error::Error>>
    }
    
    class StreamingJsonExporter <<struct>> {
        - writer: BufWriter<File>
        - block_stack: Vec<Block>
        --
        + new<P: AsRef<Path>>(path: P): Result<StreamingJsonExporter, std::io::Error>
        + finish(): Result<(), std::io::Error>
        - write_block(block: &Block): Result<(), Box<dyn std::error::Error>>
    }
    
    class XmlConverterModule <<module>> {
        + convert_file_to_xml_string(file_path: &str, pretty_print: bool): Result<String, Box<dyn std::error::Error>>
        + convert_string_to_xml_string(content: &str, pretty_print: bool): Result<String, Box<dyn std::error::Error>>
    }
}

package "Validation" as validation {
    enum XmlValidationError <<enum>> {
        Io(io::Error)
        XmlParsing(xml::reader::Error)
        FileNotFound(String)
        SchemaNotFound(String)
        ValidationFailed(String)
    }
    
    class XmlValidatorModule <<module>> {
        + validate_xml_file<P: AsRef<Path>>(xml_file_path: P, schema_file_path: P): XmlValidationResult
        + validate_xml_string<P: AsRef<Path>>(xml_content: &str, schema_file_path: Option<P>): XmlValidationResult
        + validate_xml_from_stdin<P: AsRef<Path>>(schema_file_path: P): XmlValidationResult
        + validate_wasot_to_xml<P: AsRef<Path>>(wasot_file_path: P, schema_file_path: P, pretty_print: bool): XmlValidationResult
    }
}

package "Protobuf Support" as protobuf {
    class ProtobufSupportModule <<module>> {
        + export_to_protobuf_binary(container: &BlockContainer, output_path: &str): Result<(), Box<dyn std::error::Error>>
        + export_to_protobuf_json(container: &BlockContainer, output_path: &str, pretty: bool): Result<(), Box<dyn std::error::Error>>
        + import_from_protobuf_binary(file_path: &str): Result<BlockContainer, Box<dyn std::error::Error>>
        + import_from_protobuf_json(file_path: &str): Result<BlockContainer, Box<dyn std::error::Error>>
    }
}

package "CLI Application" as cli {
    class Cli <<struct>> {
        + command: Commands
    }
    
    enum Commands <<enum>> {
        Parse
        Blocks
        Demo
        Xml
        ExportAst
        Validate
        ExportProtobuf
        ImportProtobuf
        --
        Contains file paths and options
        for each command variant
    }
    
    class EventStats <<struct>> {
        - blocks_started: usize
        - blocks_finished: usize
        - max_depth: usize
        - total_content_lines: usize
        - block_types: HashMap<String, usize>
        - start_time: Instant
        - finish_time: Option<Instant>
        --
        + new(): EventStats
        + record_start(block_type: &str, depth: usize)
        + record_finish(content_lines: usize)
        + duration(): Duration
        + print_summary()
    }
    
    class DetailedEventLogger <<struct>> {
        - show_events: bool
        - show_parameters: bool
        - show_content_preview: bool
        - stats: Arc<Mutex<EventStats>>
        - event_count: usize
        --
        + new(show_events: bool, show_parameters: bool, show_content_preview: bool): DetailedEventLogger
        + get_stats(): Arc<Mutex<EventStats>>
        + print_block_details(block: &Block, prefix: &str)
    }
}

package "Library Module" as lib {
    class LibModule <<module>> {
        + Re-exports all public APIs
        + block: Block, BlockContainer
        + block_parser: BlockParser
        + document_parser: parse_file, DocumentParser
        + events: BlockEvent, BlockEventListener
        + json_exporter: JsonLinesExporter
        + params: parse_params, ParsedParams
        + parser: MetaLine, QuotedString
        + protobuf_support: export/import functions
        + tokenizer: tokenization functions
        + xml_converter: XmlConverter
        + xml_validator: validation functions
    }
}

' Relationships - Core Data
MetaLine *-- QuotedString : inline_text
MetaLine *-- Id : id
Block *-- QuotedString : inline_text
Block *-- ParsedParams : params
Block *-- Id : id
Block *-- Block : children
ParsedParams *-- QuotedString : args, kwargs
BlockContainer *-- Block : blocks

' Relationships - Parsing
DocumentParser *-- BlockParser : block_parser
BlockParser *-- BlockContainer : container
BlockParser *-- BlockEventPublisher : event_publisher
BlockParser *-- Block : block_stack, current_text_block

' Relationships - Events
BlockEventPublisher *-- BlockEventListener : listeners
BlockEvent *-- Block : block
BlockStartListener ..|> BlockEventListener : implements
BlockFinishListener ..|> BlockEventListener : implements
BlockLifecycleListener ..|> BlockEventListener : implements

' Relationships - Output
XmlConverter ..|> BlockEventListener : implements
XmlConverterCapture ..|> BlockEventListener : implements
XmlConverterCapture *-- XmlConverter : xml_converter
XmlConverter *-- SharedWriter : writer
JsonLinesExporter ..|> BlockEventListener : implements
StreamingJsonExporter ..|> BlockEventListener : implements

' Relationships - CLI
DetailedEventLogger ..|> BlockEventListener : implements
DetailedEventLogger *-- EventStats : stats
Cli *-- Commands : command

' Relationships - Parsing flow
ParserModule ..> MetaLine : creates
ParamsModule ..> ParsedParams : creates
TokenizerModule ..> ParamsModule : used by
SimpleTokenizerModule ..> QuotedText : creates
QuoteAwareTokenizerModule ..> QuotedToken : creates
QuoteAwareTokenizerModule ..> QuotedText : creates
DocumentParser ..> BlockContainer : produces
BlockParser ..> Block : creates

' Relationships - Output flow
DocumentParser ..> XmlConverter : uses
DocumentParser ..> JsonLinesExporter : uses
DocumentParser ..> StreamingJsonExporter : uses

note top of core_data : Core data structures for representing\nWasot documents and their metadata

note top of events : Event-driven system for monitoring\nblock lifecycle during parsing

note top of parsing : Core parsing logic that processes\nWasot syntax into hierarchical blocks

note top of tokenization : Low-level text processing utilities\nfor handling quotes, parameters, and escapes

note top of output : Export functionality for XML, JSON,\nand protobuf formats

note top of validation : XML validation against XSD schemas

note top of protobuf : Binary and JSON protobuf serialization\nfor cross-language compatibility

note top of cli : Command-line interface with multiple\nsubcommands and detailed event logging

note top of lib : Public API re-exports for library usage

@enduml
