1 /*
2  * Copyright (C) 2023 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 package com.android.hoststubgen.filters
17 
18 enum class FilterPolicy {
19     /**
20      * Keep the item in the stub jar file, so tests can use it.
21      */
22     Stub,
23 
24     /**
25      * Keep the item in the impl jar file, but not in the stub file. Tests cannot use it directly,
26      * but indirectly.
27      */
28     Keep,
29 
30     /**
31      * Only used for types. Keep the class in the stub, and also all its members.
32      * But each member can have another annotations to override it.
33      */
34     StubClass,
35 
36     /**
37      * Only used for types. Keep the class in the impl, not in the stub, and also all its members.
38      * But each member can have another annotations to override it.
39      */
40     KeepClass,
41 
42     /**
43      * Same as [Stub], but replace it with a "substitution" method. Only usable with methods.
44      */
45     SubstituteAndStub,
46 
47     /**
48      * Same as [Keep], but replace it with a "substitution" method. Only usable with methods.
49      */
50     SubstituteAndKeep,
51 
52     /**
53      * Only usable with methods. The item will be kept in the impl jar file, but when called,
54      * it'll throw.
55      */
56     Throw,
57 
58     /**
59      * Only usable with methods. The item will be kept in the impl jar file, but when called,
60      * it'll no-op.  Currently only supported for methods returning `void`.
61      */
62     Ignore,
63 
64     /**
65      * Remove the item completely.
66      */
67     Remove;
68 
69     val isSubstitute: Boolean
70         get() = this == SubstituteAndStub || this == SubstituteAndKeep
71 
72     val needsInStub: Boolean
73         get() = this == Stub || this == StubClass || this == SubstituteAndStub
74 
75     val needsInImpl: Boolean
76         get() = this != Remove
77 
78     /** Returns whether a policy can be used with classes */
79     val isUsableWithClasses: Boolean
80         get() {
81             return when (this) {
82                 Stub, StubClass, Keep, KeepClass, Remove -> true
83                 else -> false
84             }
85         }
86 
87     /** Returns whether a policy can be used with fields. */
88     val isUsableWithFields: Boolean
89         get() {
90             return when (this) {
91                 Stub, Keep, Remove -> true
92                 else -> false
93             }
94         }
95 
96     /** Returns whether a policy can be used with methods */
97     val isUsableWithMethods: Boolean
98         get() {
99             return when (this) {
100                 StubClass, KeepClass -> false
101                 else -> true
102             }
103         }
104 
105     /** Returns whether a policy is a class-wide one. */
106     val isClassWidePolicy: Boolean
107         get() {
108             return when (this) {
109                 StubClass, KeepClass -> true
110                 else -> false
111             }
112         }
113 
114     /** Returns whether a policy is considered supported. */
115     val isSupported: Boolean
116         get() {
117             return when (this) {
118                 // TODO: handle native method with no substitution as being unsupported
119                 Stub, StubClass, Keep, KeepClass, SubstituteAndStub, SubstituteAndKeep -> true
120                 else -> false
121             }
122         }
123 
getSubstitutionBasePolicynull124     fun getSubstitutionBasePolicy(): FilterPolicy {
125         return when (this) {
126             SubstituteAndKeep -> Keep
127             SubstituteAndStub -> Stub
128             else -> this
129         }
130     }
131 
132     /**
133      * Convert {Stub,Keep}Class to the corresponding Stub or Keep.
134      */
resolveClassWidePolicynull135     fun resolveClassWidePolicy(): FilterPolicy {
136         return when (this) {
137             StubClass -> Stub
138             KeepClass -> Keep
139             else -> this
140         }
141     }
142 
143     /**
144      * Create a [FilterPolicyWithReason] with a given reason.
145      */
withReasonnull146     fun withReason(reason: String): FilterPolicyWithReason {
147         return FilterPolicyWithReason(this, reason)
148     }
149 }
150