@@ -75,6 +75,12 @@ export class Document extends MaybeDocument {
75
75
private readonly converter ?: ( value : api . Value ) => FieldValue
76
76
) {
77
77
super ( key , version ) ;
78
+ assert (
79
+ this . objectValue !== undefined ||
80
+ ( this . proto !== undefined && this . converter !== undefined ) ,
81
+ 'If objectValue is not defined, proto and converter need to be set.'
82
+ ) ;
83
+
78
84
this . hasLocalMutations = ! ! options . hasLocalMutations ;
79
85
this . hasCommittedMutations = ! ! options . hasCommittedMutations ;
80
86
}
@@ -83,11 +89,6 @@ export class Document extends MaybeDocument {
83
89
if ( this . objectValue ) {
84
90
return this . objectValue . field ( path ) ;
85
91
} else {
86
- assert (
87
- this . proto !== undefined && this . converter !== undefined ,
88
- 'Expected proto and converter to be defined.'
89
- ) ;
90
-
91
92
if ( ! this . fieldValueCache ) {
92
93
// TODO(b/136090445): Remove the cache when `getField` is no longer
93
94
// called during Query ordering.
@@ -103,42 +104,21 @@ export class Document extends MaybeDocument {
103
104
// deserialize the value at the requested field path. This speeds up
104
105
// Query execution as query filters can discard documents based on a
105
106
// single field.
106
- let protoValue : api . Value | undefined = this . proto ! . fields [
107
- path . firstSegment ( )
108
- ] ;
109
- for ( let i = 1 ; protoValue !== undefined && i < path . length ; ++ i ) {
110
- if ( protoValue . mapValue ) {
111
- protoValue = protoValue . mapValue . fields [ path . get ( i ) ] ;
112
- } else {
113
- protoValue = undefined ;
114
- }
115
- }
116
-
107
+ const protoValue = this . getProtoField ( path ) ;
117
108
if ( protoValue === undefined ) {
118
109
fieldValue = null ;
119
110
} else {
120
111
fieldValue = this . converter ! ( protoValue ) ;
121
112
}
122
-
123
113
this . fieldValueCache . set ( canonicalPath , fieldValue ) ;
124
114
}
125
115
126
116
return fieldValue ! ;
127
117
}
128
118
}
129
119
130
- fieldValue ( path : FieldPath ) : unknown {
131
- const field = this . field ( path ) ;
132
- return field ? field . value ( ) : undefined ;
133
- }
134
-
135
120
data ( ) : ObjectValue {
136
121
if ( ! this . objectValue ) {
137
- assert (
138
- this . proto !== undefined && this . converter !== undefined ,
139
- 'Expected proto and converter to be defined.'
140
- ) ;
141
-
142
122
let result = ObjectValue . EMPTY ;
143
123
obj . forEach ( this . proto ! . fields , ( key : string , value : api . Value ) => {
144
124
result = result . set ( new FieldPath ( [ key ] ) , this . converter ! ( value ) ) ;
@@ -180,6 +160,27 @@ export class Document extends MaybeDocument {
180
160
return this . hasLocalMutations || this . hasCommittedMutations ;
181
161
}
182
162
163
+ /**
164
+ * Returns a the nested Protobuf value for 'path`. Can only be called if
165
+ * the Protobuf was provided at construction time.
166
+ * */
167
+ private getProtoField ( path : FieldPath ) : api . Value | undefined {
168
+ assert (
169
+ this . proto !== undefined ,
170
+ "Can't call getProtoField() when proto is not defined"
171
+ ) ;
172
+ let protoValue : api . Value | undefined = this . proto ! . fields [
173
+ path . firstSegment ( )
174
+ ] ;
175
+ for ( let i = 1 ; i < path . length ; ++ i ) {
176
+ if ( ! protoValue || ! protoValue . mapValue ) {
177
+ return undefined ;
178
+ }
179
+ protoValue = protoValue . mapValue . fields [ path . get ( i ) ] ;
180
+ }
181
+ return protoValue ;
182
+ }
183
+
183
184
static compareByField ( field : FieldPath , d1 : Document , d2 : Document ) : number {
184
185
const v1 = d1 . field ( field ) ;
185
186
const v2 = d2 . field ( field ) ;
0 commit comments