cameleon_genapi/parser/
register_base.rs

1/* This Source Code Form is subject to the terms of the Mozilla Public
2 * License, v. 2.0. If a copy of the MPL was not distributed with this
3 * file, You can obtain one at https://mozilla.org/MPL/2.0/. */
4
5use crate::{
6    builder::{CacheStoreBuilder, NodeStoreBuilder, ValueStoreBuilder},
7    elem_type::AccessMode,
8    node_base::NodeElementBase,
9    store::NodeId,
10    RegisterBase,
11};
12
13use super::{
14    elem_name::{
15        ACCESS_MODE, ADDRESS, CACHEABLE, INT_SWISS_KNIFE, POLLING_TIME, P_ADDRESS, P_INDEX,
16        P_INVALIDATOR, STREAMABLE,
17    },
18    xml, Parse,
19};
20
21impl RegisterBase {
22    pub(super) fn store_invalidators(
23        &self,
24        target: NodeId,
25        cache_builder: &mut impl CacheStoreBuilder,
26    ) {
27        for invalidator in &self.p_invalidators {
28            cache_builder.store_invalidator(*invalidator, target);
29        }
30    }
31}
32
33impl Parse for RegisterBase {
34    fn parse(
35        node: &mut xml::Node,
36        node_builder: &mut impl NodeStoreBuilder,
37        value_builder: &mut impl ValueStoreBuilder,
38        cache_builder: &mut impl CacheStoreBuilder,
39    ) -> Self {
40        let elem_base: NodeElementBase = node.parse(node_builder, value_builder, cache_builder);
41
42        let streamable = node
43            .parse_if(STREAMABLE, node_builder, value_builder, cache_builder)
44            .unwrap_or_default();
45        let mut address_kinds = vec![];
46        while let Some(addr_kind) = node
47            .parse_if(ADDRESS, node_builder, value_builder, cache_builder)
48            .or_else(|| node.parse_if(INT_SWISS_KNIFE, node_builder, value_builder, cache_builder))
49            .or_else(|| node.parse_if(P_ADDRESS, node_builder, value_builder, cache_builder))
50            .or_else(|| node.parse_if(P_INDEX, node_builder, value_builder, cache_builder))
51        {
52            address_kinds.push(addr_kind);
53        }
54        let length = node.parse(node_builder, value_builder, cache_builder);
55        let access_mode = node
56            .parse_if(ACCESS_MODE, node_builder, value_builder, cache_builder)
57            .unwrap_or(AccessMode::RO);
58        let p_port = node.parse(node_builder, value_builder, cache_builder);
59        let cacheable = node
60            .parse_if(CACHEABLE, node_builder, value_builder, cache_builder)
61            .unwrap_or_default();
62        let polling_time = node.parse_if(POLLING_TIME, node_builder, value_builder, cache_builder);
63        let p_invalidators =
64            node.parse_while(P_INVALIDATOR, node_builder, value_builder, cache_builder);
65
66        // Ensure `ElementBase` doesn't consume `p]invalidator`.
67        debug_assert!(elem_base.p_invalidators.is_empty());
68
69        Self {
70            elem_base,
71            streamable,
72            address_kinds,
73            length,
74            access_mode,
75            p_port,
76            cacheable,
77            polling_time,
78            p_invalidators,
79        }
80    }
81}