code: public static QuerySnapshot withChanges(
        final Query query,
        Timestamp readTime,
        final DocumentSet documentSet,
        final List<DocumentChange> documentChanges) {
      return new QuerySnapshot(query, readTime) {
        volatile List<QueryDocumentSnapshot> documents;
  
        @Nonnull
        @Override
        public List<QueryDocumentSnapshot> getDocuments() {
          if (documents == null) {
            synchronized (documentSet) {
              if (documents == null) {
                documents = documentSet.toList();
              }
            }
          }
          return Collections.unmodifiableList(documents);
        }
  
        @Nonnull
        @Override
        public List<DocumentChange> getDocumentChanges() {
          return Collections.unmodifiableList(documentChanges);
        }
  
        @Override
        public int size() {
          return documentSet.size();
        }
  
        @Override
        public boolean equals(Object o) {
          if (this == o) {
            return true;
          }
          if (o == null || getClass() != o.getClass()) {
            return false;
          }
          QuerySnapshot that = (QuerySnapshot) o;
          return Objects.equals(query, that.query)
              && Objects.equals(this.size(), that.size())
              && Objects.equals(this.getDocumentChanges(), that.getDocumentChanges())
              && Objects.equals(this.getDocuments(), that.getDocuments());
        }
  
        @Override
        public int hashCode() {
          return Objects.hash(query, this.getDocumentChanges(), this.getDocuments());
        }
      };
    }
docs: Creates a new QuerySnapshot representing a snapshot of a Query with changed documents.