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.HiddenApiRestriction; 34 import com.android.tools.smali.dexlib2.Opcodes; 35 import com.android.tools.smali.dexlib2.ValueType; 36 import com.android.tools.smali.dexlib2.iface.Annotation; 37 import com.android.tools.smali.dexlib2.iface.AnnotationElement; 38 import com.android.tools.smali.dexlib2.iface.MethodImplementation; 39 import com.android.tools.smali.dexlib2.iface.MethodParameter; 40 import com.android.tools.smali.dexlib2.iface.reference.CallSiteReference; 41 import com.android.tools.smali.dexlib2.iface.reference.FieldReference; 42 import com.android.tools.smali.dexlib2.iface.reference.MethodHandleReference; 43 import com.android.tools.smali.dexlib2.iface.reference.MethodProtoReference; 44 import com.android.tools.smali.dexlib2.iface.reference.MethodReference; 45 import com.android.tools.smali.dexlib2.iface.reference.Reference; 46 import com.android.tools.smali.dexlib2.iface.reference.StringReference; 47 import com.android.tools.smali.dexlib2.iface.reference.TypeReference; 48 import com.android.tools.smali.dexlib2.iface.value.AnnotationEncodedValue; 49 import com.android.tools.smali.dexlib2.iface.value.ArrayEncodedValue; 50 import com.android.tools.smali.dexlib2.iface.value.BooleanEncodedValue; 51 import com.android.tools.smali.dexlib2.iface.value.ByteEncodedValue; 52 import com.android.tools.smali.dexlib2.iface.value.CharEncodedValue; 53 import com.android.tools.smali.dexlib2.iface.value.DoubleEncodedValue; 54 import com.android.tools.smali.dexlib2.iface.value.EncodedValue; 55 import com.android.tools.smali.dexlib2.iface.value.EnumEncodedValue; 56 import com.android.tools.smali.dexlib2.iface.value.FieldEncodedValue; 57 import com.android.tools.smali.dexlib2.iface.value.FloatEncodedValue; 58 import com.android.tools.smali.dexlib2.iface.value.IntEncodedValue; 59 import com.android.tools.smali.dexlib2.iface.value.LongEncodedValue; 60 import com.android.tools.smali.dexlib2.iface.value.MethodEncodedValue; 61 import com.android.tools.smali.dexlib2.iface.value.MethodHandleEncodedValue; 62 import com.android.tools.smali.dexlib2.iface.value.MethodTypeEncodedValue; 63 import com.android.tools.smali.dexlib2.iface.value.ShortEncodedValue; 64 import com.android.tools.smali.dexlib2.iface.value.StringEncodedValue; 65 import com.android.tools.smali.dexlib2.iface.value.TypeEncodedValue; 66 import com.android.tools.smali.dexlib2.util.FieldUtil; 67 import com.android.tools.smali.dexlib2.writer.DexWriter; 68 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderAnnotationEncodedValue; 69 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderArrayEncodedValue; 70 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderBooleanEncodedValue; 71 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderByteEncodedValue; 72 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderCharEncodedValue; 73 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderDoubleEncodedValue; 74 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue; 75 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderEnumEncodedValue; 76 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderFieldEncodedValue; 77 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderFloatEncodedValue; 78 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderIntEncodedValue; 79 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderLongEncodedValue; 80 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderMethodEncodedValue; 81 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderMethodHandleEncodedValue; 82 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderMethodTypeEncodedValue; 83 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderNullEncodedValue; 84 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderShortEncodedValue; 85 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderStringEncodedValue; 86 import com.android.tools.smali.dexlib2.writer.builder.BuilderEncodedValues.BuilderTypeEncodedValue; 87 import com.android.tools.smali.util.ArraySortedSet; 88 import com.android.tools.smali.util.CollectionUtils; 89 import com.android.tools.smali.util.ExceptionWithContext; 90 import com.android.tools.smali.util.IteratorUtils; 91 import com.android.tools.smali.util.TransformedIterator; 92 import com.android.tools.smali.dexlib2.writer.util.StaticInitializerUtil; 93 94 import javax.annotation.Nonnull; 95 import javax.annotation.Nullable; 96 import java.io.IOException; 97 import java.util.Collections; 98 import java.util.HashSet; 99 import java.util.Iterator; 100 import java.util.List; 101 import java.util.Set; 102 import java.util.SortedSet; 103 import java.util.function.Function; 104 import java.util.stream.Collectors; 105 106 public class DexBuilder extends DexWriter<BuilderStringReference, BuilderStringReference, BuilderTypeReference, 107 BuilderTypeReference, BuilderMethodProtoReference, BuilderFieldReference, BuilderMethodReference, 108 BuilderClassDef, BuilderCallSiteReference, BuilderMethodHandleReference, BuilderAnnotation, BuilderAnnotationSet, BuilderTypeList, 109 BuilderField, BuilderMethod, BuilderArrayEncodedValue, BuilderEncodedValue, BuilderAnnotationElement, 110 BuilderStringPool, BuilderTypePool, BuilderProtoPool, BuilderFieldPool, BuilderMethodPool, BuilderClassPool, 111 BuilderCallSitePool, BuilderMethodHandlePool, BuilderTypeListPool, BuilderAnnotationPool, 112 BuilderAnnotationSetPool, BuilderEncodedArrayPool> { 113 DexBuilder(@onnull Opcodes opcodes)114 public DexBuilder(@Nonnull Opcodes opcodes) { 115 super(opcodes); 116 } 117 getSectionProvider()118 @Nonnull @Override protected SectionProvider getSectionProvider() { 119 return new DexBuilderSectionProvider(); 120 } 121 internField(@onnull String definingClass, @Nonnull String name, @Nonnull String type, int accessFlags, @Nullable EncodedValue initialValue, @Nonnull Set<? extends Annotation> annotations, @Nonnull Set<HiddenApiRestriction> hiddenApiRestrictions)122 @Nonnull public BuilderField internField(@Nonnull String definingClass, 123 @Nonnull String name, 124 @Nonnull String type, 125 int accessFlags, 126 @Nullable EncodedValue initialValue, 127 @Nonnull Set<? extends Annotation> annotations, 128 @Nonnull Set<HiddenApiRestriction> hiddenApiRestrictions) { 129 return new BuilderField(fieldSection.internField(definingClass, name, type), 130 accessFlags, 131 internNullableEncodedValue(initialValue), 132 annotationSetSection.internAnnotationSet(annotations), 133 hiddenApiRestrictions); 134 } 135 internMethod(@onnull String definingClass, @Nonnull String name, @Nullable List<? extends MethodParameter> parameters, @Nonnull String returnType, int accessFlags, @Nonnull Set<? extends Annotation> annotations, @Nonnull Set<HiddenApiRestriction> hiddenApiRestrictions, @Nullable MethodImplementation methodImplementation)136 @Nonnull public BuilderMethod internMethod(@Nonnull String definingClass, 137 @Nonnull String name, 138 @Nullable List<? extends MethodParameter> parameters, 139 @Nonnull String returnType, 140 int accessFlags, 141 @Nonnull Set<? extends Annotation> annotations, 142 @Nonnull Set<HiddenApiRestriction> hiddenApiRestrictions, 143 @Nullable MethodImplementation methodImplementation) { 144 if (parameters == null) { 145 parameters = Collections.emptyList(); 146 } 147 return new BuilderMethod(methodSection.internMethod(definingClass, name, parameters, returnType), 148 internMethodParameters(parameters), 149 accessFlags, 150 annotationSetSection.internAnnotationSet(annotations), 151 hiddenApiRestrictions, 152 methodImplementation); 153 } 154 internClassDef(@onnull String type, int accessFlags, @Nullable String superclass, @Nullable List<String> interfaces, @Nullable String sourceFile, @Nonnull Set<? extends Annotation> annotations, @Nullable Iterable<? extends BuilderField> fields, @Nullable Iterable<? extends BuilderMethod> methods)155 @Nonnull public BuilderClassDef internClassDef(@Nonnull String type, 156 int accessFlags, 157 @Nullable String superclass, 158 @Nullable List<String> interfaces, 159 @Nullable String sourceFile, 160 @Nonnull Set<? extends Annotation> annotations, 161 @Nullable Iterable<? extends BuilderField> fields, 162 @Nullable Iterable<? extends BuilderMethod> methods) { 163 if (interfaces == null) { 164 interfaces = Collections.emptyList(); 165 } else { 166 Set<String> interfaces_copy = new HashSet<>(interfaces); 167 Iterator<String> interfaceIterator = interfaces.iterator(); 168 while (interfaceIterator.hasNext()) { 169 String iface = interfaceIterator.next(); 170 if (!interfaces_copy.contains(iface)) { 171 interfaceIterator.remove(); 172 } else { 173 interfaces_copy.remove(iface); 174 } 175 } 176 } 177 178 SortedSet<BuilderField> staticFields = null; 179 SortedSet<BuilderField> instanceFields = null; 180 BuilderArrayEncodedValue internedStaticInitializers = null; 181 if (fields != null) { 182 staticFields = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(), 183 IteratorUtils.toList((Iterator<? extends BuilderField>) IteratorUtils 184 .filter(fields, FieldUtil.FIELD_IS_STATIC))); 185 instanceFields = ArraySortedSet.copyOf(CollectionUtils.naturalOrdering(), 186 IteratorUtils.toList((Iterator<? extends BuilderField>) IteratorUtils 187 .filter(fields, FieldUtil.FIELD_IS_INSTANCE))); 188 ArrayEncodedValue staticInitializers = StaticInitializerUtil 189 .getStaticInitializers(staticFields); 190 if (staticInitializers != null) { 191 internedStaticInitializers = encodedArraySection.internArrayEncodedValue(staticInitializers); 192 } 193 } 194 195 return classSection.internClass(new BuilderClassDef(typeSection.internType(type), 196 accessFlags, 197 typeSection.internNullableType(superclass), 198 typeListSection.internTypeList(interfaces), 199 stringSection.internNullableString(sourceFile), 200 annotationSetSection.internAnnotationSet(annotations), 201 staticFields, 202 instanceFields, 203 methods, 204 internedStaticInitializers)); 205 } 206 internCallSite(@onnull CallSiteReference callSiteReference)207 public BuilderCallSiteReference internCallSite(@Nonnull CallSiteReference callSiteReference) { 208 return callSiteSection.internCallSite(callSiteReference); 209 } 210 internMethodHandle(@onnull MethodHandleReference methodHandleReference)211 public BuilderMethodHandleReference internMethodHandle(@Nonnull MethodHandleReference methodHandleReference) { 212 return methodHandleSection.internMethodHandle(methodHandleReference); 213 } 214 internStringReference(@onnull String string)215 @Nonnull public BuilderStringReference internStringReference(@Nonnull String string) { 216 return stringSection.internString(string); 217 } 218 internNullableStringReference(@ullable String string)219 @Nullable public BuilderStringReference internNullableStringReference(@Nullable String string) { 220 if (string != null) { 221 return internStringReference(string); 222 } 223 return null; 224 } 225 internTypeReference(@onnull String type)226 @Nonnull public BuilderTypeReference internTypeReference(@Nonnull String type) { 227 return typeSection.internType(type); 228 } 229 internNullableTypeReference(@ullable String type)230 @Nullable public BuilderTypeReference internNullableTypeReference(@Nullable String type) { 231 if (type != null) { 232 return internTypeReference(type); 233 } 234 return null; 235 } 236 internFieldReference(@onnull FieldReference field)237 @Nonnull public BuilderFieldReference internFieldReference(@Nonnull FieldReference field) { 238 return fieldSection.internField(field); 239 } 240 internMethodReference(@onnull MethodReference method)241 @Nonnull public BuilderMethodReference internMethodReference(@Nonnull MethodReference method) { 242 return methodSection.internMethod(method); 243 } 244 internMethodProtoReference(@onnull MethodProtoReference methodProto)245 @Nonnull public BuilderMethodProtoReference internMethodProtoReference(@Nonnull MethodProtoReference methodProto) { 246 return protoSection.internMethodProto(methodProto); 247 } 248 internReference(@onnull Reference reference)249 @Nonnull public BuilderReference internReference(@Nonnull Reference reference) { 250 if (reference instanceof StringReference) { 251 return internStringReference(((StringReference)reference).getString()); 252 } 253 if (reference instanceof TypeReference) { 254 return internTypeReference(((TypeReference)reference).getType()); 255 } 256 if (reference instanceof MethodReference) { 257 return internMethodReference((MethodReference)reference); 258 } 259 if (reference instanceof FieldReference) { 260 return internFieldReference((FieldReference)reference); 261 } 262 if (reference instanceof MethodProtoReference) { 263 return internMethodProtoReference((MethodProtoReference) reference); 264 } 265 if (reference instanceof CallSiteReference) { 266 return internCallSite((CallSiteReference) reference); 267 } 268 if (reference instanceof MethodHandleReference) { 269 return internMethodHandle((MethodHandleReference) reference); 270 } 271 throw new IllegalArgumentException("Could not determine type of reference"); 272 } 273 internMethodParameters( @ullable List<? extends MethodParameter> methodParameters)274 @Nonnull private List<BuilderMethodParameter> internMethodParameters( 275 @Nullable List<? extends MethodParameter> methodParameters) { 276 if (methodParameters == null) { 277 return Collections.emptyList(); 278 } 279 return Collections.unmodifiableList(methodParameters.stream().map(methodParam -> 280 internMethodParameter(methodParam)).collect(Collectors.toList())); 281 } 282 internMethodParameter(@onnull MethodParameter methodParameter)283 @Nonnull private BuilderMethodParameter internMethodParameter(@Nonnull MethodParameter methodParameter) { 284 return new BuilderMethodParameter( 285 typeSection.internType(methodParameter.getType()), 286 stringSection.internNullableString(methodParameter.getName()), 287 annotationSetSection.internAnnotationSet(methodParameter.getAnnotations())); 288 } 289 writeEncodedValue(@onnull InternalEncodedValueWriter writer, @Nonnull BuilderEncodedValue encodedValue)290 @Override protected void writeEncodedValue(@Nonnull InternalEncodedValueWriter writer, 291 @Nonnull BuilderEncodedValue encodedValue) throws IOException { 292 switch (encodedValue.getValueType()) { 293 case ValueType.ANNOTATION: 294 BuilderAnnotationEncodedValue annotationEncodedValue = (BuilderAnnotationEncodedValue)encodedValue; 295 writer.writeAnnotation(annotationEncodedValue.typeReference, annotationEncodedValue.elements); 296 break; 297 case ValueType.ARRAY: 298 BuilderArrayEncodedValue arrayEncodedValue = (BuilderArrayEncodedValue)encodedValue; 299 writer.writeArray(arrayEncodedValue.elements); 300 break; 301 case ValueType.BOOLEAN: 302 writer.writeBoolean(((BooleanEncodedValue)encodedValue).getValue()); 303 break; 304 case ValueType.BYTE: 305 writer.writeByte(((ByteEncodedValue)encodedValue).getValue()); 306 break; 307 case ValueType.CHAR: 308 writer.writeChar(((CharEncodedValue)encodedValue).getValue()); 309 break; 310 case ValueType.DOUBLE: 311 writer.writeDouble(((DoubleEncodedValue)encodedValue).getValue()); 312 break; 313 case ValueType.ENUM: 314 writer.writeEnum(((BuilderEnumEncodedValue)encodedValue).getValue()); 315 break; 316 case ValueType.FIELD: 317 writer.writeField(((BuilderFieldEncodedValue)encodedValue).fieldReference); 318 break; 319 case ValueType.FLOAT: 320 writer.writeFloat(((FloatEncodedValue)encodedValue).getValue()); 321 break; 322 case ValueType.INT: 323 writer.writeInt(((IntEncodedValue)encodedValue).getValue()); 324 break; 325 case ValueType.LONG: 326 writer.writeLong(((LongEncodedValue)encodedValue).getValue()); 327 break; 328 case ValueType.METHOD: 329 writer.writeMethod(((BuilderMethodEncodedValue)encodedValue).methodReference); 330 break; 331 case ValueType.NULL: 332 writer.writeNull(); 333 break; 334 case ValueType.SHORT: 335 writer.writeShort(((ShortEncodedValue)encodedValue).getValue()); 336 break; 337 case ValueType.STRING: 338 writer.writeString(((BuilderStringEncodedValue)encodedValue).stringReference); 339 break; 340 case ValueType.TYPE: 341 writer.writeType(((BuilderTypeEncodedValue)encodedValue).typeReference); 342 break; 343 case ValueType.METHOD_TYPE: 344 writer.writeMethodType(((BuilderMethodTypeEncodedValue) encodedValue).methodProtoReference); 345 break; 346 case ValueType.METHOD_HANDLE: 347 writer.writeMethodHandle(((BuilderMethodHandleEncodedValue) encodedValue).methodHandleReference); 348 break; 349 default: 350 throw new ExceptionWithContext("Unrecognized value type: %d", encodedValue.getValueType()); 351 } 352 } 353 internAnnotationElements( @onnull Set<? extends AnnotationElement> elements)354 @Nonnull Set<? extends BuilderAnnotationElement> internAnnotationElements( 355 @Nonnull Set<? extends AnnotationElement> elements) { 356 return Collections.unmodifiableSet(elements.stream().map(annotationElement -> 357 internAnnotationElement(annotationElement)).collect(Collectors.toSet())); 358 } 359 internAnnotationElement(@onnull AnnotationElement annotationElement)360 @Nonnull private BuilderAnnotationElement internAnnotationElement(@Nonnull AnnotationElement annotationElement) { 361 return new BuilderAnnotationElement(stringSection.internString(annotationElement.getName()), 362 internEncodedValue(annotationElement.getValue())); 363 } 364 internNullableEncodedValue(@ullable EncodedValue encodedValue)365 @Nullable BuilderEncodedValue internNullableEncodedValue(@Nullable EncodedValue encodedValue) { 366 if (encodedValue == null) { 367 return null; 368 } 369 return internEncodedValue(encodedValue); 370 } 371 internEncodedValue(@onnull EncodedValue encodedValue)372 @Nonnull BuilderEncodedValue internEncodedValue(@Nonnull EncodedValue encodedValue) { 373 switch (encodedValue.getValueType()) { 374 case ValueType.ANNOTATION: 375 return internAnnotationEncodedValue((AnnotationEncodedValue)encodedValue); 376 case ValueType.ARRAY: 377 return internArrayEncodedValue((ArrayEncodedValue)encodedValue); 378 case ValueType.BOOLEAN: 379 boolean value = ((BooleanEncodedValue)encodedValue).getValue(); 380 return value? BuilderBooleanEncodedValue.TRUE_VALUE:BuilderBooleanEncodedValue.FALSE_VALUE; 381 case ValueType.BYTE: 382 return new BuilderByteEncodedValue(((ByteEncodedValue)encodedValue).getValue()); 383 case ValueType.CHAR: 384 return new BuilderCharEncodedValue(((CharEncodedValue)encodedValue).getValue()); 385 case ValueType.DOUBLE: 386 return new BuilderDoubleEncodedValue(((DoubleEncodedValue)encodedValue).getValue()); 387 case ValueType.ENUM: 388 return internEnumEncodedValue((EnumEncodedValue)encodedValue); 389 case ValueType.FIELD: 390 return internFieldEncodedValue((FieldEncodedValue)encodedValue); 391 case ValueType.FLOAT: 392 return new BuilderFloatEncodedValue(((FloatEncodedValue)encodedValue).getValue()); 393 case ValueType.INT: 394 return new BuilderIntEncodedValue(((IntEncodedValue)encodedValue).getValue()); 395 case ValueType.LONG: 396 return new BuilderLongEncodedValue(((LongEncodedValue)encodedValue).getValue()); 397 case ValueType.METHOD: 398 return internMethodEncodedValue((MethodEncodedValue)encodedValue); 399 case ValueType.NULL: 400 return BuilderNullEncodedValue.INSTANCE; 401 case ValueType.SHORT: 402 return new BuilderShortEncodedValue(((ShortEncodedValue)encodedValue).getValue()); 403 case ValueType.STRING: 404 return internStringEncodedValue((StringEncodedValue)encodedValue); 405 case ValueType.TYPE: 406 return internTypeEncodedValue((TypeEncodedValue)encodedValue); 407 case ValueType.METHOD_TYPE: 408 return internMethodTypeEncodedValue((MethodTypeEncodedValue) encodedValue); 409 case ValueType.METHOD_HANDLE: 410 return internMethodHandleEncodedValue((MethodHandleEncodedValue) encodedValue); 411 default: 412 throw new ExceptionWithContext("Unexpected encoded value type: %d", encodedValue.getValueType()); 413 } 414 } 415 internAnnotationEncodedValue(@onnull AnnotationEncodedValue value)416 @Nonnull private BuilderAnnotationEncodedValue internAnnotationEncodedValue(@Nonnull AnnotationEncodedValue value) { 417 return new BuilderAnnotationEncodedValue( 418 typeSection.internType(value.getType()), 419 internAnnotationElements(value.getElements())); 420 } 421 internArrayEncodedValue(@onnull ArrayEncodedValue value)422 @Nonnull private BuilderArrayEncodedValue internArrayEncodedValue(@Nonnull ArrayEncodedValue value) { 423 return new BuilderArrayEncodedValue(Collections.unmodifiableList(value.getValue().stream() 424 .map(encodedVal -> internEncodedValue(encodedVal)).collect(Collectors.toList()))); 425 } 426 internEnumEncodedValue(@onnull EnumEncodedValue value)427 @Nonnull private BuilderEnumEncodedValue internEnumEncodedValue(@Nonnull EnumEncodedValue value) { 428 return new BuilderEnumEncodedValue(fieldSection.internField(value.getValue())); 429 } 430 internFieldEncodedValue(@onnull FieldEncodedValue value)431 @Nonnull private BuilderFieldEncodedValue internFieldEncodedValue(@Nonnull FieldEncodedValue value) { 432 return new BuilderFieldEncodedValue(fieldSection.internField(value.getValue())); 433 } 434 internMethodEncodedValue(@onnull MethodEncodedValue value)435 @Nonnull private BuilderMethodEncodedValue internMethodEncodedValue(@Nonnull MethodEncodedValue value) { 436 return new BuilderMethodEncodedValue(methodSection.internMethod(value.getValue())); 437 } 438 internStringEncodedValue(@onnull StringEncodedValue string)439 @Nonnull private BuilderStringEncodedValue internStringEncodedValue(@Nonnull StringEncodedValue string) { 440 return new BuilderStringEncodedValue(stringSection.internString(string.getValue())); 441 } 442 internTypeEncodedValue(@onnull TypeEncodedValue type)443 @Nonnull private BuilderTypeEncodedValue internTypeEncodedValue(@Nonnull TypeEncodedValue type) { 444 return new BuilderTypeEncodedValue(typeSection.internType(type.getValue())); 445 } 446 internMethodTypeEncodedValue( @onnull MethodTypeEncodedValue methodType)447 @Nonnull private BuilderMethodTypeEncodedValue internMethodTypeEncodedValue( 448 @Nonnull MethodTypeEncodedValue methodType) { 449 return new BuilderMethodTypeEncodedValue(protoSection.internMethodProto(methodType.getValue())); 450 } 451 internMethodHandleEncodedValue( @onnull MethodHandleEncodedValue methodHandle)452 @Nonnull private BuilderMethodHandleEncodedValue internMethodHandleEncodedValue( 453 @Nonnull MethodHandleEncodedValue methodHandle) { 454 return new BuilderMethodHandleEncodedValue(methodHandleSection.internMethodHandle(methodHandle.getValue())); 455 } 456 457 protected class DexBuilderSectionProvider extends SectionProvider { getStringSection()458 @Nonnull @Override public BuilderStringPool getStringSection() { 459 return new BuilderStringPool(); 460 } 461 getTypeSection()462 @Nonnull @Override public BuilderTypePool getTypeSection() { 463 return new BuilderTypePool(DexBuilder.this); 464 } 465 getProtoSection()466 @Nonnull @Override public BuilderProtoPool getProtoSection() { 467 return new BuilderProtoPool(DexBuilder.this); 468 } 469 getFieldSection()470 @Nonnull @Override public BuilderFieldPool getFieldSection() { 471 return new BuilderFieldPool(DexBuilder.this); 472 } 473 getMethodSection()474 @Nonnull @Override public BuilderMethodPool getMethodSection() { 475 return new BuilderMethodPool(DexBuilder.this); 476 } 477 getClassSection()478 @Nonnull @Override public BuilderClassPool getClassSection() { 479 return new BuilderClassPool(DexBuilder.this); 480 } 481 getCallSiteSection()482 @Nonnull @Override public BuilderCallSitePool getCallSiteSection() { 483 return new BuilderCallSitePool(DexBuilder.this); 484 } 485 getMethodHandleSection()486 @Nonnull @Override public BuilderMethodHandlePool getMethodHandleSection() { 487 return new BuilderMethodHandlePool(DexBuilder.this); 488 } 489 getTypeListSection()490 @Nonnull @Override public BuilderTypeListPool getTypeListSection() { 491 return new BuilderTypeListPool(DexBuilder.this); 492 } 493 getAnnotationSection()494 @Nonnull @Override public BuilderAnnotationPool getAnnotationSection() { 495 return new BuilderAnnotationPool(DexBuilder.this); 496 } 497 getAnnotationSetSection()498 @Nonnull @Override public BuilderAnnotationSetPool getAnnotationSetSection() { 499 return new BuilderAnnotationSetPool(DexBuilder.this); 500 } 501 getEncodedArraySection()502 @Nonnull @Override public BuilderEncodedArrayPool getEncodedArraySection() { 503 return new BuilderEncodedArrayPool(DexBuilder.this); 504 } 505 } 506 } 507