1818
1919#include < memory>
2020
21+ #import " Firestore/Source/API/FIRDocumentReference+Internal.h"
2122#import " Firestore/Source/API/FIRFirestore+Internal.h"
2223#import " Firestore/Source/API/FIRPipelineBridge+Internal.h"
24+ #import " Firestore/Source/API/FSTUserDataReader.h"
25+ #import " Firestore/Source/API/FSTUserDataWriter.h"
2326
27+ #include " Firestore/Protos/nanopb/google/firestore/v1/document.nanopb.h"
28+
29+ #include " Firestore/core/src/api/document_reference.h"
2430#include " Firestore/core/src/api/expressions.h"
2531#include " Firestore/core/src/api/pipeline.h"
2632#include " Firestore/core/src/api/pipeline_result.h"
3238
3339using firebase::firestore::api::CollectionSource;
3440using firebase::firestore::api::Constant;
41+ using firebase::firestore::api::DocumentReference;
3542using firebase::firestore::api::Expr;
3643using firebase::firestore::api::Field;
3744using firebase::firestore::api::FunctionExpr;
3845using firebase::firestore::api::Pipeline;
3946using firebase::firestore::api::Where;
4047using firebase::firestore::util::MakeCallback;
48+ using firebase::firestore::util::MakeNSString;
4149using firebase::firestore::util::MakeString;
4250
4351NS_ASSUME_NONNULL_BEGIN
@@ -57,47 +65,60 @@ - (id)init:(NSString *)name {
5765 return self;
5866}
5967
60- - (std::shared_ptr<api::Expr>)cpp_expr {
68+ - (std::shared_ptr<api::Expr>)cppExprWithReader : (FSTUserDataReader *) reader {
6169 return field;
6270}
6371
6472@end
6573
6674@implementation FIRConstantBridge {
6775 std::shared_ptr<Constant> constant;
76+ id _input;
77+ Boolean isUserDataRead;
6878}
69- - (id )init : (NSNumber *) value {
79+ - (id )init : (id ) input {
7080 self = [super init ];
71- if (self) {
72- constant = std::make_shared<Constant>(value.doubleValue );
73- }
81+ _input = input;
82+ isUserDataRead = NO ;
7483 return self;
7584}
7685
77- - (std::shared_ptr<api::Expr>)cpp_expr {
86+ - (std::shared_ptr<api::Expr>)cppExprWithReader : (FSTUserDataReader *)reader {
87+ if (!isUserDataRead) {
88+ constant = std::make_shared<Constant>([reader parsedQueryValue: _input]);
89+ }
90+
91+ isUserDataRead = YES ;
7892 return constant;
7993}
8094
8195@end
8296
8397@implementation FIRFunctionExprBridge {
8498 std::shared_ptr<FunctionExpr> eq;
99+ NSString *_name;
100+ NSArray <FIRExprBridge *> *_args;
101+ Boolean isUserDataRead;
85102}
86103
87104- (nonnull id )initWithName : (NSString *)name Args : (nonnull NSArray <FIRExprBridge *> *)args {
88105 self = [super init ];
89- if (self) {
106+ _name = name;
107+ _args = args;
108+ isUserDataRead = NO ;
109+ return self;
110+ }
111+
112+ - (std::shared_ptr<api::Expr>)cppExprWithReader : (FSTUserDataReader *)reader {
113+ if (!isUserDataRead) {
90114 std::vector<std::shared_ptr<Expr>> cpp_args;
91- for (FIRExprBridge *arg in args ) {
92- cpp_args.push_back (arg. cpp_expr );
115+ for (FIRExprBridge *arg in _args ) {
116+ cpp_args.push_back ([ arg cppExprWithReader: reader] );
93117 }
94-
95- eq = std::make_shared<FunctionExpr>(MakeString (name), std::move (cpp_args));
118+ eq = std::make_shared<FunctionExpr>(MakeString (_name), std::move (cpp_args));
96119 }
97- return self;
98- }
99120
100- - (std::shared_ptr<api::Expr>) cpp_expr {
121+ isUserDataRead = YES ;
101122 return eq;
102123}
103124
@@ -118,63 +139,142 @@ - (id)initWithPath:(NSString *)path {
118139 return self;
119140}
120141
121- - (std::shared_ptr<api::Stage>)cpp_stage {
142+ - (std::shared_ptr<api::Stage>)cppStageWithReader : (FSTUserDataReader *) reader {
122143 return collection_source;
123144}
124145
125146@end
126147
127148@implementation FIRWhereStageBridge {
149+ FIRExprBridge *_exprBridge;
150+ Boolean isUserDataRead;
128151 std::shared_ptr<Where> where;
129152}
130153
131154- (id )initWithExpr : (FIRExprBridge *)expr {
132155 self = [super init ];
133156 if (self) {
134- where = std::make_shared<Where>(expr.cpp_expr );
157+ _exprBridge = expr;
158+ isUserDataRead = NO ;
135159 }
136160 return self;
137161}
138162
139- - (std::shared_ptr<api::Stage>)cpp_stage {
163+ - (std::shared_ptr<api::Stage>)cppStageWithReader : (FSTUserDataReader *)reader {
164+ if (!isUserDataRead) {
165+ where = std::make_shared<Where>([_exprBridge cppExprWithReader: reader]);
166+ }
167+
168+ isUserDataRead = YES ;
140169 return where;
141170}
142171
143172@end
144173
174+ @interface __FIRPipelineSnapshotBridge ()
175+
176+ @property (nonatomic , strong , readwrite ) NSArray <__FIRPipelineSnapshotBridge *> *results;
177+
178+ @end
179+
145180@implementation __FIRPipelineSnapshotBridge {
146- absl::optional<api::PipelineSnapshot> pipeline;
181+ absl::optional<api::PipelineSnapshot> snapshot_;
182+ NSMutableArray <__FIRPipelineResultBridge *> *results_;
147183}
148184
149185- (id )initWithCppSnapshot : (api::PipelineSnapshot)snapshot {
150186 self = [super init ];
151187 if (self) {
152- pipeline = std::move (snapshot);
188+ snapshot_ = std::move (snapshot);
189+ if (!snapshot_.has_value ()) {
190+ results_ = nil ;
191+ } else {
192+ NSMutableArray <__FIRPipelineResultBridge *> *results = [NSMutableArray array ];
193+ for (auto &result : snapshot_.value ().results ()) {
194+ [results addObject: [[__FIRPipelineResultBridge alloc ]
195+ initWithCppResult: result
196+ db: snapshot_.value ().firestore ()]];
197+ }
198+ results_ = results;
199+ }
153200 }
154201
155202 return self;
156203}
157204
205+ - (NSArray <__FIRPipelineResultBridge *> *)results {
206+ return results_;
207+ }
208+
158209@end
159210
160- @implementation FIRPipelineBridge {
161- std::shared_ptr<Pipeline> pipeline;
211+ @implementation __FIRPipelineResultBridge {
212+ api::PipelineResult _result;
213+ std::shared_ptr<api::Firestore> _db;
162214}
163215
164- - (id )initWithStages : (NSArray <FIRStageBridge *> *)stages db : (FIRFirestore *)db {
216+ - (FIRDocumentReference *)reference {
217+ if (!_result.internal_key ().has_value ()) return nil ;
218+
219+ return [[FIRDocumentReference alloc ] initWithKey: _result.internal_key ().value () firestore: _db];
220+ }
221+
222+ - (NSString *)documentID {
223+ if (!_result.document_id ().has_value ()) {
224+ return nil ;
225+ }
226+
227+ return MakeNSString (_result.document_id ().value ());
228+ }
229+
230+ - (id )initWithCppResult : (api::PipelineResult)result db : (std::shared_ptr<api::Firestore>)db {
165231 self = [super init ];
166232 if (self) {
167- std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
168- for (FIRStageBridge *stage in stages) {
169- cpp_stages.push_back (stage.cpp_stage );
170- }
171- pipeline = std::make_shared<Pipeline>(cpp_stages, db.wrapped );
233+ _result = std::move (result);
234+ _db = std::move (db);
172235 }
236+
173237 return self;
174238}
175239
240+ - (nullable NSDictionary <NSString *, id> *)data {
241+ return [self dataWithServerTimestampBehavior: FIRServerTimestampBehaviorNone];
242+ }
243+
244+ - (nullable NSDictionary <NSString *, id> *)dataWithServerTimestampBehavior :
245+ (FIRServerTimestampBehavior)serverTimestampBehavior {
246+ absl::optional<firebase::firestore::google_firestore_v1_Value> data =
247+ _result.internal_value ()->Get ();
248+ if (!data) return nil ;
249+
250+ FSTUserDataWriter *dataWriter =
251+ [[FSTUserDataWriter alloc ] initWithFirestore: _db
252+ serverTimestampBehavior: serverTimestampBehavior];
253+ return [dataWriter convertedValue: *data];
254+ }
255+
256+ @end
257+
258+ @implementation FIRPipelineBridge {
259+ NSArray <FIRStageBridge *> *_stages;
260+ FIRFirestore *firestore;
261+ std::shared_ptr<Pipeline> pipeline;
262+ }
263+
264+ - (id )initWithStages : (NSArray <FIRStageBridge *> *)stages db : (FIRFirestore *)db {
265+ _stages = stages;
266+ firestore = db;
267+ return [super init ];
268+ }
269+
176270- (void )executeWithCompletion : (void (^)(__FIRPipelineSnapshotBridge *_Nullable result,
177271 NSError *_Nullable error))completion {
272+ std::vector<std::shared_ptr<firebase::firestore::api::Stage>> cpp_stages;
273+ for (FIRStageBridge *stage in _stages) {
274+ cpp_stages.push_back ([stage cppStageWithReader: firestore.dataReader]);
275+ }
276+ pipeline = std::make_shared<Pipeline>(cpp_stages, firestore.wrapped );
277+
178278 pipeline->execute ([completion](StatusOr<api::PipelineSnapshot> maybe_value) {
179279 if (maybe_value.ok ()) {
180280 __FIRPipelineSnapshotBridge *bridge = [[__FIRPipelineSnapshotBridge alloc ]
0 commit comments