1 /* 2 * Copyright 2013, Google LLC 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions are 6 * met: 7 * 8 * * Redistributions of source code must retain the above copyright 9 * notice, this list of conditions and the following disclaimer. 10 * * Redistributions in binary form must reproduce the above 11 * copyright notice, this list of conditions and the following disclaimer 12 * in the documentation and/or other materials provided with the 13 * distribution. 14 * * Neither the name of Google LLC nor the names of its 15 * contributors may be used to endorse or promote products derived from 16 * this software without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 */ 30 31 package com.android.tools.smali.dexlib2.writer.builder; 32 33 import com.android.tools.smali.dexlib2.base.value.BaseAnnotationEncodedValue; 34 import com.android.tools.smali.dexlib2.base.value.BaseArrayEncodedValue; 35 import com.android.tools.smali.dexlib2.base.value.BaseBooleanEncodedValue; 36 import com.android.tools.smali.dexlib2.base.value.BaseEnumEncodedValue; 37 import com.android.tools.smali.dexlib2.base.value.BaseFieldEncodedValue; 38 import com.android.tools.smali.dexlib2.base.value.BaseMethodEncodedValue; 39 import com.android.tools.smali.dexlib2.base.value.BaseMethodHandleEncodedValue; 40 import com.android.tools.smali.dexlib2.base.value.BaseMethodTypeEncodedValue; 41 import com.android.tools.smali.dexlib2.base.value.BaseNullEncodedValue; 42 import com.android.tools.smali.dexlib2.base.value.BaseStringEncodedValue; 43 import com.android.tools.smali.dexlib2.base.value.BaseTypeEncodedValue; 44 import com.android.tools.smali.dexlib2.immutable.value.ImmutableByteEncodedValue; 45 import com.android.tools.smali.dexlib2.immutable.value.ImmutableCharEncodedValue; 46 import com.android.tools.smali.dexlib2.immutable.value.ImmutableDoubleEncodedValue; 47 import com.android.tools.smali.dexlib2.immutable.value.ImmutableFloatEncodedValue; 48 import com.android.tools.smali.dexlib2.immutable.value.ImmutableIntEncodedValue; 49 import com.android.tools.smali.dexlib2.immutable.value.ImmutableLongEncodedValue; 50 import com.android.tools.smali.dexlib2.immutable.value.ImmutableShortEncodedValue; 51 import com.android.tools.smali.dexlib2.writer.DexWriter; 52 import com.android.tools.smali.util.ExceptionWithContext; 53 import com.android.tools.smali.dexlib2.iface.value.EncodedValue; 54 55 import javax.annotation.Nonnull; 56 import java.util.List; 57 import java.util.Set; 58 59 public abstract class BuilderEncodedValues { 60 public static interface BuilderEncodedValue extends EncodedValue { 61 } 62 63 public static class BuilderAnnotationEncodedValue extends BaseAnnotationEncodedValue 64 implements BuilderEncodedValue { 65 @Nonnull final BuilderTypeReference typeReference; 66 @Nonnull final Set<? extends BuilderAnnotationElement> elements; 67 BuilderAnnotationEncodedValue(@onnull BuilderTypeReference typeReference, @Nonnull Set<? extends BuilderAnnotationElement> elements)68 BuilderAnnotationEncodedValue(@Nonnull BuilderTypeReference typeReference, 69 @Nonnull Set<? extends BuilderAnnotationElement> elements) { 70 this.typeReference = typeReference; 71 this.elements = elements; 72 } 73 getType()74 @Nonnull @Override public String getType() { 75 return typeReference.getType(); 76 } 77 getElements()78 @Nonnull @Override public Set<? extends BuilderAnnotationElement> getElements() { 79 return elements; 80 } 81 } 82 83 public static class BuilderArrayEncodedValue extends BaseArrayEncodedValue implements BuilderEncodedValue { 84 @Nonnull final List<? extends BuilderEncodedValue> elements; 85 int offset = DexWriter.NO_OFFSET; 86 BuilderArrayEncodedValue(@onnull List<? extends BuilderEncodedValue> elements)87 BuilderArrayEncodedValue(@Nonnull List<? extends BuilderEncodedValue> elements) { 88 this.elements = elements; 89 } 90 getValue()91 @Nonnull @Override public List<? extends EncodedValue> getValue() { 92 return elements; 93 } 94 } 95 96 @Nonnull defaultValueForType(String type)97 public static BuilderEncodedValue defaultValueForType(String type) { 98 switch (type.charAt(0)) { 99 case 'Z': 100 return BuilderBooleanEncodedValue.FALSE_VALUE; 101 case 'B': 102 return new BuilderByteEncodedValue((byte)0); 103 case 'S': 104 return new BuilderShortEncodedValue((short)0); 105 case 'C': 106 return new BuilderCharEncodedValue((char)0); 107 case 'I': 108 return new BuilderIntEncodedValue(0); 109 case 'J': 110 return new BuilderLongEncodedValue(0); 111 case 'F': 112 return new BuilderFloatEncodedValue(0); 113 case 'D': 114 return new BuilderDoubleEncodedValue(0); 115 case 'L': 116 case '[': 117 return BuilderNullEncodedValue.INSTANCE; 118 default: 119 throw new ExceptionWithContext("Unrecognized type: %s", type); 120 } 121 } 122 123 public static class BuilderBooleanEncodedValue extends BaseBooleanEncodedValue 124 implements BuilderEncodedValue { 125 public static final BuilderBooleanEncodedValue TRUE_VALUE = new BuilderBooleanEncodedValue(true); 126 public static final BuilderBooleanEncodedValue FALSE_VALUE = new BuilderBooleanEncodedValue(false); 127 128 private final boolean value; 129 BuilderBooleanEncodedValue(boolean value)130 private BuilderBooleanEncodedValue(boolean value) { 131 this.value = value; 132 } 133 getValue()134 @Override public boolean getValue() { 135 return value; 136 } 137 } 138 139 public static class BuilderByteEncodedValue extends ImmutableByteEncodedValue 140 implements BuilderEncodedValue { BuilderByteEncodedValue(byte value)141 public BuilderByteEncodedValue(byte value) { 142 super(value); 143 } 144 } 145 146 public static class BuilderCharEncodedValue extends ImmutableCharEncodedValue 147 implements BuilderEncodedValue { BuilderCharEncodedValue(char value)148 public BuilderCharEncodedValue(char value) { 149 super(value); 150 } 151 } 152 153 public static class BuilderDoubleEncodedValue extends ImmutableDoubleEncodedValue 154 implements BuilderEncodedValue { BuilderDoubleEncodedValue(double value)155 public BuilderDoubleEncodedValue(double value) { 156 super(value); 157 } 158 } 159 160 public static class BuilderEnumEncodedValue extends BaseEnumEncodedValue 161 implements BuilderEncodedValue { 162 @Nonnull final BuilderFieldReference enumReference; 163 BuilderEnumEncodedValue(@onnull BuilderFieldReference enumReference)164 BuilderEnumEncodedValue(@Nonnull BuilderFieldReference enumReference) { 165 this.enumReference = enumReference; 166 } 167 getValue()168 @Nonnull @Override public BuilderFieldReference getValue() { 169 return enumReference; 170 } 171 } 172 173 public static class BuilderFieldEncodedValue extends BaseFieldEncodedValue 174 implements BuilderEncodedValue { 175 @Nonnull final BuilderFieldReference fieldReference; 176 BuilderFieldEncodedValue(@onnull BuilderFieldReference fieldReference)177 BuilderFieldEncodedValue(@Nonnull BuilderFieldReference fieldReference) { 178 this.fieldReference = fieldReference; 179 } 180 getValue()181 @Nonnull @Override public BuilderFieldReference getValue() { 182 return fieldReference; 183 } 184 } 185 186 public static class BuilderFloatEncodedValue extends ImmutableFloatEncodedValue 187 implements BuilderEncodedValue { BuilderFloatEncodedValue(float value)188 public BuilderFloatEncodedValue(float value) { 189 super(value); 190 } 191 } 192 193 public static class BuilderIntEncodedValue extends ImmutableIntEncodedValue 194 implements BuilderEncodedValue { BuilderIntEncodedValue(int value)195 public BuilderIntEncodedValue(int value) { 196 super(value); 197 } 198 } 199 200 public static class BuilderLongEncodedValue extends ImmutableLongEncodedValue 201 implements BuilderEncodedValue { BuilderLongEncodedValue(long value)202 public BuilderLongEncodedValue(long value) { 203 super(value); 204 } 205 } 206 207 public static class BuilderMethodEncodedValue extends BaseMethodEncodedValue 208 implements BuilderEncodedValue { 209 @Nonnull final BuilderMethodReference methodReference; 210 BuilderMethodEncodedValue(@onnull BuilderMethodReference methodReference)211 BuilderMethodEncodedValue(@Nonnull BuilderMethodReference methodReference) { 212 this.methodReference = methodReference; 213 } 214 getValue()215 @Override public BuilderMethodReference getValue() { 216 return methodReference; 217 } 218 } 219 220 public static class BuilderNullEncodedValue extends BaseNullEncodedValue 221 implements BuilderEncodedValue { 222 public static final BuilderNullEncodedValue INSTANCE = new BuilderNullEncodedValue(); 223 BuilderNullEncodedValue()224 private BuilderNullEncodedValue() {} 225 } 226 227 public static class BuilderShortEncodedValue extends ImmutableShortEncodedValue 228 implements BuilderEncodedValue { BuilderShortEncodedValue(short value)229 public BuilderShortEncodedValue(short value) { 230 super(value); 231 } 232 } 233 234 public static class BuilderStringEncodedValue extends BaseStringEncodedValue 235 implements BuilderEncodedValue { 236 @Nonnull final BuilderStringReference stringReference; 237 BuilderStringEncodedValue(@onnull BuilderStringReference stringReference)238 BuilderStringEncodedValue(@Nonnull BuilderStringReference stringReference) { 239 this.stringReference = stringReference; 240 } 241 getValue()242 @Nonnull @Override public String getValue() { 243 return stringReference.getString(); 244 } 245 } 246 247 public static class BuilderTypeEncodedValue extends BaseTypeEncodedValue 248 implements BuilderEncodedValue { 249 @Nonnull final BuilderTypeReference typeReference; 250 BuilderTypeEncodedValue(@onnull BuilderTypeReference typeReference)251 BuilderTypeEncodedValue(@Nonnull BuilderTypeReference typeReference) { 252 this.typeReference = typeReference; 253 } 254 getValue()255 @Nonnull @Override public String getValue() { 256 return typeReference.getType(); 257 } 258 } 259 260 public static class BuilderMethodTypeEncodedValue extends BaseMethodTypeEncodedValue 261 implements BuilderEncodedValue { 262 @Nonnull final BuilderMethodProtoReference methodProtoReference; 263 BuilderMethodTypeEncodedValue(@onnull BuilderMethodProtoReference methodProtoReference)264 public BuilderMethodTypeEncodedValue(@Nonnull BuilderMethodProtoReference methodProtoReference) { 265 this.methodProtoReference = methodProtoReference; 266 } 267 getValue()268 @Nonnull @Override public BuilderMethodProtoReference getValue() { return methodProtoReference; } 269 } 270 271 public static class BuilderMethodHandleEncodedValue extends BaseMethodHandleEncodedValue 272 implements BuilderEncodedValue { 273 @Nonnull final BuilderMethodHandleReference methodHandleReference; 274 BuilderMethodHandleEncodedValue(@onnull BuilderMethodHandleReference methodHandleReference)275 public BuilderMethodHandleEncodedValue(@Nonnull BuilderMethodHandleReference methodHandleReference) { 276 this.methodHandleReference = methodHandleReference; 277 } 278 getValue()279 @Nonnull @Override public BuilderMethodHandleReference getValue() { return methodHandleReference; } 280 } 281 } 282