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.collect.Maps; 3542627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.base.reference.BaseMethodReference; 3642627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.iface.reference.MethodReference; 3742627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport org.jf.dexlib2.writer.MethodSection; 3842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 3942627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport javax.annotation.Nonnull; 4042627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.Collection; 4142627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.List; 4242627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.Map.Entry; 4342627b850c8f68a594f105e04b97c512b292b698Ben Gruverimport java.util.concurrent.ConcurrentMap; 4442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 4542627b850c8f68a594f105e04b97c512b292b698Ben Gruverclass BuilderMethodPool implements MethodSection<BuilderStringReference, BuilderTypeReference, 4642627b850c8f68a594f105e04b97c512b292b698Ben Gruver BuilderProtoReference, BuilderMethodReference, BuilderMethod>{ 4742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final BuilderContext context; 4842627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final ConcurrentMap<MethodReference, BuilderMethodReference> internedItems = 4942627b850c8f68a594f105e04b97c512b292b698Ben Gruver Maps.newConcurrentMap(); 5042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 5142627b850c8f68a594f105e04b97c512b292b698Ben Gruver BuilderMethodPool(@Nonnull BuilderContext context) { 5242627b850c8f68a594f105e04b97c512b292b698Ben Gruver this.context = context; 5342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 5442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 5542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull public BuilderMethodReference internMethod(@Nonnull MethodReference methodReference) { 5642627b850c8f68a594f105e04b97c512b292b698Ben Gruver BuilderMethodReference ret = internedItems.get(methodReference); 5742627b850c8f68a594f105e04b97c512b292b698Ben Gruver if (ret != null) { 5842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return ret; 5942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 6042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 6142627b850c8f68a594f105e04b97c512b292b698Ben Gruver BuilderMethodReference dexPoolMethodReference = new BuilderMethodReference( 6242627b850c8f68a594f105e04b97c512b292b698Ben Gruver context.typePool.internType(methodReference.getDefiningClass()), 6342627b850c8f68a594f105e04b97c512b292b698Ben Gruver context.stringPool.internString(methodReference.getName()), 6442627b850c8f68a594f105e04b97c512b292b698Ben Gruver context.protoPool.internProto(methodReference)); 6542627b850c8f68a594f105e04b97c512b292b698Ben Gruver ret = internedItems.putIfAbsent(dexPoolMethodReference, dexPoolMethodReference); 6642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return ret==null?dexPoolMethodReference:ret; 6742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 6842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 6942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull public BuilderMethodReference internMethod(@Nonnull String definingClass, @Nonnull String name, 7042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull List<? extends CharSequence> parameters, 7142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull String returnType) { 7242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return internMethod(new MethodKey(definingClass, name, parameters, returnType)); 7342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 7442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 7542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 7642627b850c8f68a594f105e04b97c512b292b698Ben Gruver public BuilderTypeReference getDefiningClass(@Nonnull BuilderMethodReference key) { 7742627b850c8f68a594f105e04b97c512b292b698Ben Gruver return key.definingClass; 7842627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 7942627b850c8f68a594f105e04b97c512b292b698Ben Gruver 8042627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override 8142627b850c8f68a594f105e04b97c512b292b698Ben Gruver public BuilderProtoReference getPrototype(@Nonnull BuilderMethodReference key) { 8242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return key.proto; 8342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 8442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 8542627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public BuilderProtoReference getPrototype(@Nonnull BuilderMethod builderMethod) { 8642627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderMethod.methodReference.proto; 8742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 8842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 8942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public BuilderStringReference getName(@Nonnull BuilderMethodReference key) { 9042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return key.name; 9142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 9242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 9342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getMethodIndex(@Nonnull BuilderMethod builderMethod) { 9442627b850c8f68a594f105e04b97c512b292b698Ben Gruver return builderMethod.methodReference.index; 9542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 9642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 9742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override public int getItemIndex(@Nonnull BuilderMethodReference key) { 9842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return key.index; 9942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 10042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 10142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public Collection<? extends Entry<? extends BuilderMethodReference, Integer>> getItems() { 10242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return new BuilderMapEntryCollection<BuilderMethodReference>(internedItems.values()) { 10342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override protected int getValue(@Nonnull BuilderMethodReference key) { 10442627b850c8f68a594f105e04b97c512b292b698Ben Gruver return key.index; 10542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 10642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 10742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Override protected int setValue(@Nonnull BuilderMethodReference key, int value) { 10842627b850c8f68a594f105e04b97c512b292b698Ben Gruver int prev = key.index; 10942627b850c8f68a594f105e04b97c512b292b698Ben Gruver key.index = value; 11042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return prev; 11142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 11242627b850c8f68a594f105e04b97c512b292b698Ben Gruver }; 11342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 11442627b850c8f68a594f105e04b97c512b292b698Ben Gruver 11542627b850c8f68a594f105e04b97c512b292b698Ben Gruver private static class MethodKey extends BaseMethodReference implements MethodReference { 11642627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final String definingClass; 11742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final String name; 11842627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final List<? extends CharSequence> parameterTypes; 11942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull private final String returnType; 12042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 12142627b850c8f68a594f105e04b97c512b292b698Ben Gruver public MethodKey(@Nonnull String definingClass, @Nonnull String name, 12242627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull List<? extends CharSequence> parameterTypes, @Nonnull String returnType) { 12342627b850c8f68a594f105e04b97c512b292b698Ben Gruver this.definingClass = definingClass; 12442627b850c8f68a594f105e04b97c512b292b698Ben Gruver this.name = name; 12542627b850c8f68a594f105e04b97c512b292b698Ben Gruver this.parameterTypes = parameterTypes; 12642627b850c8f68a594f105e04b97c512b292b698Ben Gruver this.returnType = returnType; 12742627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 12842627b850c8f68a594f105e04b97c512b292b698Ben Gruver 12942627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public String getDefiningClass() { 13042627b850c8f68a594f105e04b97c512b292b698Ben Gruver return definingClass; 13142627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 13242627b850c8f68a594f105e04b97c512b292b698Ben Gruver 13342627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public String getName() { 13442627b850c8f68a594f105e04b97c512b292b698Ben Gruver return name; 13542627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 13642627b850c8f68a594f105e04b97c512b292b698Ben Gruver 13742627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public List<? extends CharSequence> getParameterTypes() { 13842627b850c8f68a594f105e04b97c512b292b698Ben Gruver return parameterTypes; 13942627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 14042627b850c8f68a594f105e04b97c512b292b698Ben Gruver 14142627b850c8f68a594f105e04b97c512b292b698Ben Gruver @Nonnull @Override public String getReturnType() { 14242627b850c8f68a594f105e04b97c512b292b698Ben Gruver return returnType; 14342627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 14442627b850c8f68a594f105e04b97c512b292b698Ben Gruver } 14542627b850c8f68a594f105e04b97c512b292b698Ben Gruver} 146