@@ -121,6 +121,10 @@ impl StringTable {
121
121
#[ derive( Debug , Clone , Copy , PartialEq ) ]
122
122
pub struct NodeRef ( pub usize ) ;
123
123
124
+ /// Represents an offset to a node whose schema hasn't been committed yet
125
+ #[ derive( Debug , Clone , Copy , PartialEq ) ]
126
+ pub struct PendingNodeRef ( pub NodeRef ) ;
127
+
124
128
#[ derive( Debug ) ]
125
129
pub struct BoolPos ( pub usize ) ;
126
130
#[ derive( Debug ) ]
@@ -152,20 +156,16 @@ where
152
156
K : Into < u8 > + Display ,
153
157
P : Into < u8 > + Display ,
154
158
{
155
- fn header (
156
- & mut self ,
157
- kind : K ,
158
- parent : NodeRef ,
159
- span : & Span ,
160
- prop_count : usize ,
161
- ) -> NodeRef ;
159
+ fn header ( & mut self , kind : K , parent : NodeRef , span : & Span )
160
+ -> PendingNodeRef ;
162
161
fn ref_field ( & mut self , prop : P ) -> FieldPos ;
163
162
fn ref_vec_field ( & mut self , prop : P , len : usize ) -> FieldArrPos ;
164
163
fn str_field ( & mut self , prop : P ) -> StrPos ;
165
164
fn bool_field ( & mut self , prop : P ) -> BoolPos ;
166
165
fn undefined_field ( & mut self , prop : P ) -> UndefPos ;
167
166
#[ allow( dead_code) ]
168
167
fn null_field ( & mut self , prop : P ) -> NullPos ;
168
+ fn commit_schema ( & mut self , offset : PendingNodeRef ) -> NodeRef ;
169
169
170
170
fn write_ref ( & mut self , pos : FieldPos , value : NodeRef ) ;
171
171
fn write_maybe_ref ( & mut self , pos : FieldPos , value : Option < NodeRef > ) ;
@@ -183,6 +183,7 @@ pub struct SerializeCtx {
183
183
str_table : StringTable ,
184
184
kind_map : Vec < usize > ,
185
185
prop_map : Vec < usize > ,
186
+ field_count : u8 ,
186
187
}
187
188
188
189
/// This is the internal context used to allocate and fill the buffer. The point
@@ -200,8 +201,9 @@ impl SerializeCtx {
200
201
start_buf : NodeRef ( 0 ) ,
201
202
buf : vec ! [ ] ,
202
203
str_table : StringTable :: new ( ) ,
203
- kind_map : vec ! [ 0 ; kind_size + 1 ] ,
204
- prop_map : vec ! [ 0 ; prop_size + 1 ] ,
204
+ kind_map : vec ! [ 0 ; kind_size] ,
205
+ prop_map : vec ! [ 0 ; prop_size] ,
206
+ field_count : 0 ,
205
207
} ;
206
208
207
209
let empty_str = ctx. str_table . insert ( "" ) ;
@@ -232,6 +234,8 @@ impl SerializeCtx {
232
234
where
233
235
P : Into < u8 > + Display + Clone ,
234
236
{
237
+ self . field_count += 1 ;
238
+
235
239
let offset = self . buf . len ( ) ;
236
240
237
241
let n: u8 = prop. clone ( ) . into ( ) ;
@@ -268,7 +272,7 @@ impl SerializeCtx {
268
272
parent : NodeRef ,
269
273
span : & Span ,
270
274
prop_count : usize ,
271
- ) -> NodeRef {
275
+ ) -> PendingNodeRef {
272
276
let offset = self . buf . len ( ) ;
273
277
274
278
// Node type fits in a u8
@@ -285,7 +289,19 @@ impl SerializeCtx {
285
289
debug_assert ! ( prop_count < 10 ) ;
286
290
self . buf . push ( prop_count as u8 ) ;
287
291
288
- NodeRef ( offset)
292
+ PendingNodeRef ( NodeRef ( offset) )
293
+ }
294
+
295
+ pub fn commit_schema ( & mut self , node_ref : PendingNodeRef ) -> NodeRef {
296
+ let mut offset = node_ref. 0 . 0 ;
297
+
298
+ // type + parentId + span lo + span hi
299
+ offset += 1 + 4 + 4 + 4 ;
300
+
301
+ self . buf [ offset] = self . field_count ;
302
+ self . field_count = 0 ;
303
+
304
+ node_ref. 0
289
305
}
290
306
291
307
/// Allocate the node header. It's always the same for every node.
@@ -299,8 +315,7 @@ impl SerializeCtx {
299
315
kind : N ,
300
316
parent : NodeRef ,
301
317
span : & Span ,
302
- prop_count : usize ,
303
- ) -> NodeRef
318
+ ) -> PendingNodeRef
304
319
where
305
320
N : Into < u8 > + Display + Clone ,
306
321
{
@@ -313,7 +328,9 @@ impl SerializeCtx {
313
328
}
314
329
}
315
330
316
- self . append_node ( n, parent, span, prop_count)
331
+ // Prop count will be filled with the actual value when the
332
+ // schema is committed.
333
+ self . append_node ( n, parent, span, 0 )
317
334
}
318
335
319
336
/// Allocate a reference property that will hold the offset of
0 commit comments