142627b850c8f68a594f105e04b97c512b292b698Ben Gruver/*
242627b850c8f68a594f105e04b97c512b292b698Ben Gruver * Copyright 2013, Google Inc.
342627b850c8f68a594f105e04b97c512b292b698Ben Gruver * All rights reserved.
442627b850c8f68a594f105e04b97c512b292b698Ben Gruver *
542627b850c8f68a594f105e04b97c512b292b698Ben Gruver * Redistribution and use in source and binary forms, with or without
642627b850c8f68a594f105e04b97c512b292b698Ben Gruver * modification, are permitted provided that the following conditions are
742627b850c8f68a594f105e04b97c512b292b698Ben Gruver * met:
842627b850c8f68a594f105e04b97c512b292b698Ben Gruver *
942627b850c8f68a594f105e04b97c512b292b698Ben Gruver *     * Redistributions of source code must retain the above copyright
1042627b850c8f68a594f105e04b97c512b292b698Ben Gruver * notice, this list of conditions and the following disclaimer.
1142627b850c8f68a594f105e04b97c512b292b698Ben Gruver *     * Redistributions in binary form must reproduce the above
1242627b850c8f68a594f105e04b97c512b292b698Ben Gruver * copyright notice, this list of conditions and the following disclaimer
1342627b850c8f68a594f105e04b97c512b292b698Ben Gruver * in the documentation and/or other materials provided with the
1442627b850c8f68a594f105e04b97c512b292b698Ben Gruver * distribution.
1542627b850c8f68a594f105e04b97c512b292b698Ben Gruver *     * Neither the name of Google Inc. nor the names of its
1642627b850c8f68a594f105e04b97c512b292b698Ben Gruver * contributors may be used to endorse or promote products derived from
1742627b850c8f68a594f105e04b97c512b292b698Ben Gruver * this software without specific prior written permission.
1842627b850c8f68a594f105e04b97c512b292b698Ben Gruver *
1942627b850c8f68a594f105e04b97c512b292b698Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2042627b850c8f68a594f105e04b97c512b292b698Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2142627b850c8f68a594f105e04b97c512b292b698Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2242627b850c8f68a594f105e04b97c512b292b698Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2342627b850c8f68a594f105e04b97c512b292b698Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
2442627b850c8f68a594f105e04b97c512b292b698Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
2542627b850c8f68a594f105e04b97c512b292b698Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
2642627b850c8f68a594f105e04b97c512b292b698Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
2742627b850c8f68a594f105e04b97c512b292b698Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
2842627b850c8f68a594f105e04b97c512b292b698Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
2942627b850c8f68a594f105e04b97c512b292b698Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3042627b850c8f68a594f105e04b97c512b292b698Ben Gruver */
3142627b850c8f68a594f105e04b97c512b292b698Ben Gruver
3242627b850c8f68a594f105e04b97c512b292b698Ben Gruverpackage org.jf.dexlib2.writer.builder;
3342627b850c8f68a594f105e04b97c512b292b698Ben Gruver
3442627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport com.google.common.base.Function;
3542627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport com.google.common.base.Predicate;
3642627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport com.google.common.collect.*;
3742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.DebugItemType;
389a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruverimport org.jf.dexlib2.builder.MutableMethodImplementation;
396f135aeb74b0a5b5720bafa2a9aaa32880f0549fBen Gruverimport org.jf.dexlib2.iface.ExceptionHandler;
4042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.Field;
41dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruverimport org.jf.dexlib2.iface.MethodImplementation;
4242627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.TryBlock;
439bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruverimport org.jf.dexlib2.iface.debug.*;
44dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruverimport org.jf.dexlib2.iface.instruction.Instruction;
459bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruverimport org.jf.dexlib2.iface.reference.StringReference;
469bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruverimport org.jf.dexlib2.iface.reference.TypeReference;
4742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.value.EncodedValue;
4842627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.util.EncodedValueUtils;
4942627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.ClassSection;
5042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.DebugWriter;
5142627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.builder.BuilderEncodedValues.BuilderEncodedValue;
5242627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.util.AbstractForwardSequentialList;
5342627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.util.CollectionUtils;
5442627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.util.ExceptionWithContext;
5542627b850c8f68a594f105e04b97c512b292b698Ben Gruver
5642627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport javax.annotation.Nonnull;
5742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport javax.annotation.Nullable;
5842627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.io.IOException;
5942627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.*;
6042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.Map.Entry;
6142627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.concurrent.ConcurrentMap;
6242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
635189797292086a051666cf8c96cf44c6a23321b6Ben Gruverpublic class BuilderClassPool extends BaseBuilderPool implements ClassSection<BuilderStringReference,
645189797292086a051666cf8c96cf44c6a23321b6Ben Gruver        BuilderTypeReference, BuilderTypeList, BuilderClassDef, BuilderField, BuilderMethod, BuilderAnnotationSet,
655189797292086a051666cf8c96cf44c6a23321b6Ben Gruver        BuilderEncodedValue> {
6642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull private final ConcurrentMap<String, BuilderClassDef> internedItems =
6742627b850c8f68a594f105e04b97c512b292b698Ben Gruver            Maps.newConcurrentMap();
6842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
695189797292086a051666cf8c96cf44c6a23321b6Ben Gruver    public BuilderClassPool(@Nonnull DexBuilder dexBuilder) {
705189797292086a051666cf8c96cf44c6a23321b6Ben Gruver        super(dexBuilder);
7142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
7242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
7342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull BuilderClassDef internClass(@Nonnull BuilderClassDef classDef) {
7442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        BuilderClassDef prev = internedItems.put(classDef.getType(), classDef);
7542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (prev != null) {
7642627b850c8f68a594f105e04b97c512b292b698Ben Gruver            throw new ExceptionWithContext("Class %s has already been interned", classDef.getType());
7742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
7842627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return classDef;
7942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
8042627b850c8f68a594f105e04b97c512b292b698Ben Gruver
8142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    private ImmutableList<BuilderClassDef> sortedClasses = null;
8242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override public Collection<? extends BuilderClassDef> getSortedClasses() {
8342627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (sortedClasses == null) {
8442627b850c8f68a594f105e04b97c512b292b698Ben Gruver            sortedClasses = Ordering.natural().immutableSortedCopy(internedItems.values());
8542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
8642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return sortedClasses;
8742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
8842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
8942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override
9042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Entry<? extends BuilderClassDef, Integer> getClassEntryByType(@Nullable BuilderTypeReference type) {
9142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (type == null) {
9242627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
9342627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
9442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
9542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        final BuilderClassDef classDef = internedItems.get(type.getType());
9642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (classDef == null) {
9742627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
9842627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
9942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
10042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return new Map.Entry<BuilderClassDef, Integer>() {
10142627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Override public BuilderClassDef getKey() {
10242627b850c8f68a594f105e04b97c512b292b698Ben Gruver                return classDef;
10342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
10442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
10542627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Override public Integer getValue() {
10642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                return classDef.classDefIndex;
10742627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
10842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
10942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Override public Integer setValue(Integer value) {
11042627b850c8f68a594f105e04b97c512b292b698Ben Gruver                return classDef.classDefIndex = value;
11142627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
11242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        };
11342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
11442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
11542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override public BuilderTypeReference getType(@Nonnull BuilderClassDef builderClassDef) {
11642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.type;
11742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
11842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
11942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getAccessFlags(@Nonnull BuilderClassDef builderClassDef) {
12042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.accessFlags;
12142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
12242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
12342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override public BuilderTypeReference getSuperclass(@Nonnull BuilderClassDef builderClassDef) {
12442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.superclass;
12542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
12642627b850c8f68a594f105e04b97c512b292b698Ben Gruver
127c456c55c40d0731edb9913fae73f16b9d94ac45bAlex Light    @Nullable @Override public BuilderTypeList getInterfaces(@Nonnull BuilderClassDef builderClassDef) {
12842627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.interfaces;
12942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
13042627b850c8f68a594f105e04b97c512b292b698Ben Gruver
13142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override public BuilderStringReference getSourceFile(@Nonnull BuilderClassDef builderClassDef) {
13242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.sourceFile;
13342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
13442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
13542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    private static final Predicate<Field> HAS_INITIALIZER = new Predicate<Field>() {
13642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        @Override
13742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        public boolean apply(Field input) {
13842627b850c8f68a594f105e04b97c512b292b698Ben Gruver            EncodedValue encodedValue = input.getInitialValue();
13942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return encodedValue != null && !EncodedValueUtils.isDefaultValue(encodedValue);
14042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
14142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    };
14242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
14342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    private static final Function<BuilderField, BuilderEncodedValue> GET_INITIAL_VALUE =
14442627b850c8f68a594f105e04b97c512b292b698Ben Gruver            new Function<BuilderField, BuilderEncodedValue>() {
14542627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Override
14642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                public BuilderEncodedValue apply(BuilderField input) {
14742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    BuilderEncodedValue initialValue = input.getInitialValue();
14842627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    if (initialValue == null) {
14942627b850c8f68a594f105e04b97c512b292b698Ben Gruver                        return BuilderEncodedValues.defaultValueForType(input.getType());
15042627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    }
15142627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    return initialValue;
15242627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
15342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            };
15442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
15542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override
15642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderEncodedValue> getStaticInitializers(@Nonnull BuilderClassDef classDef) {
15742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        final SortedSet<BuilderField> sortedStaticFields = classDef.getStaticFields();
15842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
15942627b850c8f68a594f105e04b97c512b292b698Ben Gruver        final int lastIndex = CollectionUtils.lastIndexOf(sortedStaticFields, HAS_INITIALIZER);
16042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (lastIndex > -1) {
16142627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return new AbstractCollection<BuilderEncodedValue>() {
16242627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Nonnull @Override public Iterator<BuilderEncodedValue> iterator() {
1631d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver                    Iterable<BuilderField> fields = Iterables.limit(sortedStaticFields, lastIndex + 1);
1641d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver                    return Iterables.transform(fields, GET_INITIAL_VALUE).iterator();
16542627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
16642627b850c8f68a594f105e04b97c512b292b698Ben Gruver
16742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Override public int size() {
16842627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    return lastIndex+1;
16942627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
17042627b850c8f68a594f105e04b97c512b292b698Ben Gruver            };
17142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
17242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return null;
17342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
17442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
17542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
17642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderField> getSortedStaticFields(@Nonnull BuilderClassDef builderClassDef) {
17742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.getStaticFields();
17842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
17942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
18042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
18142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderField> getSortedInstanceFields(@Nonnull BuilderClassDef builderClassDef) {
18242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.getInstanceFields();
18342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
18442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
18542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
18642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderField> getSortedFields(@Nonnull BuilderClassDef builderClassDef) {
18742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.getFields();
18842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
18942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
19042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
19142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderMethod> getSortedDirectMethods(@Nonnull BuilderClassDef builderClassDef) {
19242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.getDirectMethods();
19342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
19442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
19542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
19642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderMethod> getSortedVirtualMethods(@Nonnull BuilderClassDef builderClassDef) {
19742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.getVirtualMethods();
19842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
19942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
20042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
20142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Collection<? extends BuilderMethod> getSortedMethods(@Nonnull BuilderClassDef builderClassDef) {
20242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.getMethods();
20342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
20442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
20542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getFieldAccessFlags(@Nonnull BuilderField builderField) {
20642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderField.accessFlags;
20742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
20842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
20942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getMethodAccessFlags(@Nonnull BuilderMethod builderMethod) {
21042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderMethod.accessFlags;
21142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
21242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
21342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override public BuilderAnnotationSet getClassAnnotations(@Nonnull BuilderClassDef builderClassDef) {
21442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (builderClassDef.annotations.isEmpty()) {
21542627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
21642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
21742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.annotations;
21842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
21942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
22042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override public BuilderAnnotationSet getFieldAnnotations(@Nonnull BuilderField builderField) {
22142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (builderField.annotations.isEmpty()) {
22242627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
22342627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
22442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderField.annotations;
22542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
22642627b850c8f68a594f105e04b97c512b292b698Ben Gruver
22742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override public BuilderAnnotationSet getMethodAnnotations(@Nonnull BuilderMethod builderMethod) {
22842627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (builderMethod.annotations.isEmpty()) {
22942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
23042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
23142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderMethod.annotations;
23242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
23342627b850c8f68a594f105e04b97c512b292b698Ben Gruver
23442627b850c8f68a594f105e04b97c512b292b698Ben Gruver    private static final Predicate<BuilderMethodParameter> HAS_PARAMETER_ANNOTATIONS =
23542627b850c8f68a594f105e04b97c512b292b698Ben Gruver            new Predicate<BuilderMethodParameter>() {
23642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Override
23742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                public boolean apply(BuilderMethodParameter input) {
23842627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    return input.getAnnotations().size() > 0;
23942627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
24042627b850c8f68a594f105e04b97c512b292b698Ben Gruver            };
24142627b850c8f68a594f105e04b97c512b292b698Ben Gruver
24242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    private static final Function<BuilderMethodParameter, BuilderAnnotationSet> PARAMETER_ANNOTATIONS =
24342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            new Function<BuilderMethodParameter, BuilderAnnotationSet>() {
24442627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Override
24542627b850c8f68a594f105e04b97c512b292b698Ben Gruver                public BuilderAnnotationSet apply(BuilderMethodParameter input) {
24642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                    return input.getAnnotations();
24742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
24842627b850c8f68a594f105e04b97c512b292b698Ben Gruver            };
24942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
25042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override public List<? extends BuilderAnnotationSet> getParameterAnnotations(
25142627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Nonnull final BuilderMethod method) {
252f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver        final List<? extends BuilderMethodParameter> parameters = method.getParameters();
253f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver        boolean hasParameterAnnotations = Iterables.any(parameters, HAS_PARAMETER_ANNOTATIONS);
25442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
255f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver        if (hasParameterAnnotations) {
25642627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return new AbstractForwardSequentialList<BuilderAnnotationSet>() {
25742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Nonnull @Override public Iterator<BuilderAnnotationSet> iterator() {
2581d4637b3d94732a4eaa83b129054ee9245bed24eBen Gruver                    return Iterables.transform(parameters, PARAMETER_ANNOTATIONS).iterator();
25942627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
26042627b850c8f68a594f105e04b97c512b292b698Ben Gruver
26142627b850c8f68a594f105e04b97c512b292b698Ben Gruver                @Override public int size() {
262f6958ae4bc66ec338f5547ef3952896e219e6c33Ben Gruver                    return parameters.size();
26342627b850c8f68a594f105e04b97c512b292b698Ben Gruver                }
26442627b850c8f68a594f105e04b97c512b292b698Ben Gruver            };
26542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
26642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return null;
26742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
26842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
26942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override
2709bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver    public Iterable<? extends DebugItem> getDebugItems(@Nonnull BuilderMethod builderMethod) {
271dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver        MethodImplementation impl = builderMethod.getImplementation();
27242627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (impl == null) {
27342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
27442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
27542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return impl.getDebugItems();
27642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
27742627b850c8f68a594f105e04b97c512b292b698Ben Gruver
27842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override
27942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public Iterable<? extends BuilderStringReference> getParameterNames(@Nonnull BuilderMethod method) {
28042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return Iterables.transform(method.getParameters(), new Function<BuilderMethodParameter, BuilderStringReference>() {
28142627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Nullable @Override public BuilderStringReference apply(BuilderMethodParameter input) {
28242627b850c8f68a594f105e04b97c512b292b698Ben Gruver                return input.name;
28342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
28442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        });
28542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
28642627b850c8f68a594f105e04b97c512b292b698Ben Gruver
28742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getRegisterCount(@Nonnull BuilderMethod builderMethod) {
288dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver        MethodImplementation impl = builderMethod.getImplementation();
28942627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (impl == null) {
29042627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return 0;
29142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
292dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver        return impl.getRegisterCount();
29342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
29442627b850c8f68a594f105e04b97c512b292b698Ben Gruver
29542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nullable @Override
296dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver    public Iterable<? extends Instruction> getInstructions(@Nonnull BuilderMethod builderMethod) {
297dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver        MethodImplementation impl = builderMethod.getImplementation();
29842627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (impl == null) {
29942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return null;
30042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
30142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return impl.getInstructions();
30242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
30342627b850c8f68a594f105e04b97c512b292b698Ben Gruver
30442627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override
305dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver    public List<? extends TryBlock<? extends ExceptionHandler>> getTryBlocks(@Nonnull BuilderMethod builderMethod) {
306dff046e1b559f4f8b175bb9cdaf005419ec62cb1Ben Gruver        MethodImplementation impl = builderMethod.getImplementation();
30742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        if (impl == null) {
30842627b850c8f68a594f105e04b97c512b292b698Ben Gruver            return ImmutableList.of();
30942627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
31042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return impl.getTryBlocks();
31142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
31242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
3136f135aeb74b0a5b5720bafa2a9aaa32880f0549fBen Gruver    @Nullable @Override public BuilderTypeReference getExceptionType(@Nonnull ExceptionHandler handler) {
3146f135aeb74b0a5b5720bafa2a9aaa32880f0549fBen Gruver        return checkTypeReference(handler.getExceptionTypeReference());
31542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
31642627b850c8f68a594f105e04b97c512b292b698Ben Gruver
3179a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver    @Nonnull @Override
3189a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver    public MutableMethodImplementation makeMutableMethodImplementation(@Nonnull BuilderMethod builderMethod) {
3199a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver        MethodImplementation impl = builderMethod.getImplementation();
3209a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver        if (impl instanceof MutableMethodImplementation) {
3219a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver            return (MutableMethodImplementation)impl;
3229a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver        }
3239a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver        return new MutableMethodImplementation(impl);
3249a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver    }
3259a2de93a998958e582e9c2aa0bff7de602cc8771Ben Gruver
32642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public void setEncodedArrayOffset(@Nonnull BuilderClassDef builderClassDef, int offset) {
32742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        builderClassDef.encodedArrayOffset = offset;
32842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
32942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
33042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getEncodedArrayOffset(@Nonnull BuilderClassDef builderClassDef) {
33142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.encodedArrayOffset;
33242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
33342627b850c8f68a594f105e04b97c512b292b698Ben Gruver
33442627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public void setAnnotationDirectoryOffset(@Nonnull BuilderClassDef builderClassDef, int offset) {
33542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        builderClassDef.annotationDirectoryOffset = offset;
33642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
33742627b850c8f68a594f105e04b97c512b292b698Ben Gruver
33842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getAnnotationDirectoryOffset(@Nonnull BuilderClassDef builderClassDef) {
33942627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.annotationDirectoryOffset;
34042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
34142627b850c8f68a594f105e04b97c512b292b698Ben Gruver
34242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public void setAnnotationSetRefListOffset(@Nonnull BuilderMethod builderMethod, int offset) {
34342627b850c8f68a594f105e04b97c512b292b698Ben Gruver        builderMethod.annotationSetRefListOffset = offset;
34442627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
34542627b850c8f68a594f105e04b97c512b292b698Ben Gruver
34642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getAnnotationSetRefListOffset(@Nonnull BuilderMethod builderMethod) {
34742627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderMethod.annotationSetRefListOffset;
34842627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
34942627b850c8f68a594f105e04b97c512b292b698Ben Gruver
35042627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public void setCodeItemOffset(@Nonnull BuilderMethod builderMethod, int offset) {
35142627b850c8f68a594f105e04b97c512b292b698Ben Gruver        builderMethod.codeItemOffset = offset;
35242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
35342627b850c8f68a594f105e04b97c512b292b698Ben Gruver
35442627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getCodeItemOffset(@Nonnull BuilderMethod builderMethod) {
35542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderMethod.codeItemOffset;
35642627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
35742627b850c8f68a594f105e04b97c512b292b698Ben Gruver
3589bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver    @Nullable private BuilderStringReference checkStringReference(@Nullable StringReference stringReference) {
3599bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        if (stringReference == null) {
3609bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver            return null;
3619bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        }
3629bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        try {
3639bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver            return (BuilderStringReference)stringReference;
3649bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        } catch (ClassCastException ex) {
3659bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver            throw new IllegalStateException("Only StringReference instances returned by " +
3669bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                    "DexBuilder.internStringReference or DexBuilder.internNullableStringReference may be used.");
3679bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        }
3689bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver    }
3699bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver
3709bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver    @Nullable private BuilderTypeReference checkTypeReference(@Nullable TypeReference typeReference) {
3719bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        if (typeReference == null) {
3729bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver            return null;
3739bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        }
3749bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        try {
3759bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver            return (BuilderTypeReference)typeReference;
3769bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        } catch (ClassCastException ex) {
3779bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver            throw new IllegalStateException("Only TypeReference instances returned by " +
3789bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                    "DexBuilder.internTypeReference or DexBuilder.internNullableTypeReference may be used.");
3799bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver        }
3809bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver    }
3819bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver
38242627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override
38342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    public void writeDebugItem(@Nonnull DebugWriter<BuilderStringReference, BuilderTypeReference> writer,
3849bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                               DebugItem debugItem) throws IOException {
38542627b850c8f68a594f105e04b97c512b292b698Ben Gruver        switch (debugItem.getDebugItemType()) {
38642627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.START_LOCAL: {
3879bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                StartLocal startLocal = (StartLocal)debugItem;
38842627b850c8f68a594f105e04b97c512b292b698Ben Gruver                writer.writeStartLocal(startLocal.getCodeAddress(),
3899bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                        startLocal.getRegister(),
3909bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                        checkStringReference(startLocal.getNameReference()),
3919bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                        checkTypeReference(startLocal.getTypeReference()),
3929bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                        checkStringReference(startLocal.getSignatureReference()));
39342627b850c8f68a594f105e04b97c512b292b698Ben Gruver                break;
39442627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
39542627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.END_LOCAL: {
39642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                EndLocal endLocal = (EndLocal)debugItem;
39742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                writer.writeEndLocal(endLocal.getCodeAddress(), endLocal.getRegister());
39842627b850c8f68a594f105e04b97c512b292b698Ben Gruver                break;
39942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
40042627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.RESTART_LOCAL: {
40142627b850c8f68a594f105e04b97c512b292b698Ben Gruver                RestartLocal restartLocal = (RestartLocal)debugItem;
40242627b850c8f68a594f105e04b97c512b292b698Ben Gruver                writer.writeRestartLocal(restartLocal.getCodeAddress(), restartLocal.getRegister());
40342627b850c8f68a594f105e04b97c512b292b698Ben Gruver                break;
40442627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
40542627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.PROLOGUE_END: {
40642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                writer.writePrologueEnd(debugItem.getCodeAddress());
40742627b850c8f68a594f105e04b97c512b292b698Ben Gruver                break;
40842627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
40942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.EPILOGUE_BEGIN: {
41042627b850c8f68a594f105e04b97c512b292b698Ben Gruver                writer.writeEpilogueBegin(debugItem.getCodeAddress());
41142627b850c8f68a594f105e04b97c512b292b698Ben Gruver                break;
41242627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
41342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.LINE_NUMBER: {
41442627b850c8f68a594f105e04b97c512b292b698Ben Gruver                LineNumber lineNumber = (LineNumber)debugItem;
41542627b850c8f68a594f105e04b97c512b292b698Ben Gruver                writer.writeLineNumber(lineNumber.getCodeAddress(), lineNumber.getLineNumber());
41642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                break;
41742627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
41842627b850c8f68a594f105e04b97c512b292b698Ben Gruver            case DebugItemType.SET_SOURCE_FILE: {
4199bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                SetSourceFile setSourceFile = (SetSourceFile)debugItem;
4209bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                writer.writeSetSourceFile(setSourceFile.getCodeAddress(),
4219bbcaae91fffe74cbc90608eaa98484192b11d77Ben Gruver                        checkStringReference(setSourceFile.getSourceFileReference()));
422a37e508ffa2a512d70890c6a174c2c98ed803607Ben Gruver                break;
42342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
42442627b850c8f68a594f105e04b97c512b292b698Ben Gruver            default:
42542627b850c8f68a594f105e04b97c512b292b698Ben Gruver                throw new ExceptionWithContext("Unexpected debug item type: %d", debugItem.getDebugItemType());
42642627b850c8f68a594f105e04b97c512b292b698Ben Gruver        }
42742627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
42842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
42942627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Override public int getItemIndex(@Nonnull BuilderClassDef builderClassDef) {
43042627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return builderClassDef.classDefIndex;
43142627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
43242627b850c8f68a594f105e04b97c512b292b698Ben Gruver
43342627b850c8f68a594f105e04b97c512b292b698Ben Gruver    @Nonnull @Override public Collection<? extends Entry<? extends BuilderClassDef, Integer>> getItems() {
43442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        return new BuilderMapEntryCollection<BuilderClassDef>(internedItems.values()) {
43542627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Override protected int getValue(@Nonnull BuilderClassDef key) {
43642627b850c8f68a594f105e04b97c512b292b698Ben Gruver                return key.classDefIndex;
43742627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
43842627b850c8f68a594f105e04b97c512b292b698Ben Gruver
43942627b850c8f68a594f105e04b97c512b292b698Ben Gruver            @Override protected int setValue(@Nonnull BuilderClassDef key, int value) {
44042627b850c8f68a594f105e04b97c512b292b698Ben Gruver                int prev = key.classDefIndex;
44142627b850c8f68a594f105e04b97c512b292b698Ben Gruver                key.classDefIndex = value;
44242627b850c8f68a594f105e04b97c512b292b698Ben Gruver                return prev;
44342627b850c8f68a594f105e04b97c512b292b698Ben Gruver            }
44442627b850c8f68a594f105e04b97c512b292b698Ben Gruver        };
44542627b850c8f68a594f105e04b97c512b292b698Ben Gruver    }
44659256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver
44759256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver    @Override public int getItemCount() {
44859256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver        return internedItems.size();
44959256149f100fd06d7a5bebaa2d29a3f0847ee22Ben Gruver    }
45042627b850c8f68a594f105e04b97c512b292b698Ben Gruver}
451