10cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar/*
20cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * Copyright (C) 2017 The Android Open Source Project
30cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar *
40cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * Licensed under the Apache License, Version 2.0 (the "License");
50cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * you may not use this file except in compliance with the License.
60cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * You may obtain a copy of the License at
70cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar *
80cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar *      http://www.apache.org/licenses/LICENSE-2.0
90cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar *
100cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * Unless required by applicable law or agreed to in writing, software
110cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * distributed under the License is distributed on an "AS IS" BASIS,
120cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
130cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * See the License for the specific language governing permissions and
140cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar * limitations under the License.
150cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar */
160cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
17bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viverettepackage androidx.room.solver.binderprovider
180cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
19bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.RoomRxJava2TypeNames
20bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.ext.typeName
21bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.parser.ParsedQuery
22bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.processor.Context
23bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.processor.ProcessorErrors
24bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.solver.QueryResultBinderProvider
25bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.solver.query.result.QueryResultBinder
26bdc4c86d3dff74f6634a38e2f7b316b0e823a2c8Alan Viveretteimport androidx.room.solver.query.result.RxCallableQueryResultBinder
270cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyarimport javax.lang.model.type.DeclaredType
280cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
290cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyarsealed class RxCallableQueryResultBinderProvider(val context: Context,
300cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar                                                 val rxType: RxCallableQueryResultBinder.RxType)
310cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    : QueryResultBinderProvider {
320cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    private val hasRxJava2Artifact by lazy {
330cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        context.processingEnv.elementUtils
340cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar                .getTypeElement(RoomRxJava2TypeNames.RX_ROOM.toString()) != null
350cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    }
360cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
370cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    override fun provide(declared: DeclaredType, query: ParsedQuery): QueryResultBinder {
380cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        val typeArg = declared.typeArguments.first()
390cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        val adapter = context.typeAdapterStore.findQueryResultAdapter(typeArg, query)
4025b465c796ebee5bd7d304becbcf6a42fed53056Yigit Boyar        return RxCallableQueryResultBinder(rxType, typeArg, adapter)
410cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    }
420cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
430cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    override fun matches(declared: DeclaredType): Boolean =
440cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar            declared.typeArguments.size == 1 && matchesRxType(declared)
450cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
460cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    private fun matchesRxType(declared: DeclaredType): Boolean {
470cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        val erasure = context.processingEnv.typeUtils.erasure(declared)
480cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        val match = erasure.typeName() == rxType.className
490cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        if (match && !hasRxJava2Artifact) {
500cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar            context.logger.e(ProcessorErrors.MISSING_ROOM_RXJAVA2_ARTIFACT)
510cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        }
520cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar        return match
530cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    }
540cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar}
550cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
560cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyarclass RxSingleQueryResultBinderProvider(context: Context)
570cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    : RxCallableQueryResultBinderProvider(context, RxCallableQueryResultBinder.RxType.SINGLE)
580cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar
590cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyarclass RxMaybeQueryResultBinderProvider(context: Context)
600cf0bfe0e88f5d511a2a23495005c2da9ea91fd5Yigit Boyar    : RxCallableQueryResultBinderProvider(context, RxCallableQueryResultBinder.RxType.MAYBE)
61