• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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