+
+// restoreView returns the view of state with the limits high and low. Each line
+// must continue the one before it, and each line above level 0 must be built.
+func restoreView(state ViewState, high, low int, tree ViewNodeReader) (*View, error) {
+ v := newView(high, low)
+ v.merging = state.Merging
+ for _, pair := range state.Lines {
+ line := NodeKey{pair[0], pair[1]}
+ if line.level < 0 || line.level >= bits.UintSize-2 || line.index < 0 || line.index<<line.level != v.end {
+ return nil, fmt.Errorf("view line (%d, %d) does not start at message %d", line.level, line.index, v.end)
+ }
+
+ built, err := v.load(tree, line)
+ if err != nil {
+ return nil, fmt.Errorf("load restored view node: %w", err)
+ }
+
+ if line.level > 0 && !built {
+ return nil, fmt.Errorf("view line (%d, %d) is not built", line.level, line.index)
+ }
+
+ v.lines = append(v.lines, line)
+ v.end = nodeEnd(line.level, line.index)
+ }
+
+ return v, nil
+}