1b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver/*
2b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * Copyright 2012, Google Inc.
3b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * All rights reserved.
4b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver *
5b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * Redistribution and use in source and binary forms, with or without
6b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * modification, are permitted provided that the following conditions are
7b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * met:
8b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver *
9b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver *     * Redistributions of source code must retain the above copyright
10b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * notice, this list of conditions and the following disclaimer.
11b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver *     * Redistributions in binary form must reproduce the above
12b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * copyright notice, this list of conditions and the following disclaimer
13b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * in the documentation and/or other materials provided with the
14b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * distribution.
15b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver *     * Neither the name of Google Inc. nor the names of its
16b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * contributors may be used to endorse or promote products derived from
17b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * this software without specific prior written permission.
18b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver *
19b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver */
31b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
32b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverpackage org.jf.dexlib2.immutable.value;
33b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
34b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverimport com.google.common.base.Preconditions;
35b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverimport com.google.common.collect.ImmutableList;
36b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverimport org.jf.dexlib2.ValueType;
37b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverimport org.jf.dexlib2.iface.value.*;
384ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruverimport org.jf.util.ExceptionWithContext;
3922c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruverimport org.jf.util.ImmutableConverter;
40b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
41b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverimport javax.annotation.Nonnull;
42b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverimport javax.annotation.Nullable;
43b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
44b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruverpublic class ImmutableEncodedValueFactory {
45ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver    @Nonnull
46ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver    public static ImmutableEncodedValue of(@Nonnull EncodedValue encodedValue) {
47b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver        switch (encodedValue.getValueType()) {
48b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.BYTE:
49b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableByteEncodedValue.of((ByteEncodedValue)encodedValue);
50b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.SHORT:
51b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableShortEncodedValue.of((ShortEncodedValue)encodedValue);
52b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.CHAR:
53b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableCharEncodedValue.of((CharEncodedValue)encodedValue);
54b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.INT:
55b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableIntEncodedValue.of((IntEncodedValue)encodedValue);
56b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.LONG:
57b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableLongEncodedValue.of((LongEncodedValue)encodedValue);
58b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.FLOAT:
59b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableFloatEncodedValue.of((FloatEncodedValue)encodedValue);
60b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.DOUBLE:
61b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableDoubleEncodedValue.of((DoubleEncodedValue)encodedValue);
62b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.STRING:
63b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableStringEncodedValue.of((StringEncodedValue)encodedValue);
64b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.TYPE:
65b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableTypeEncodedValue.of((TypeEncodedValue)encodedValue);
66b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.FIELD:
67b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableFieldEncodedValue.of((FieldEncodedValue)encodedValue);
68b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.METHOD:
69b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableMethodEncodedValue.of((MethodEncodedValue)encodedValue);
70b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.ENUM:
71b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableEnumEncodedValue.of((EnumEncodedValue)encodedValue);
72b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.ARRAY:
73b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableArrayEncodedValue.of((ArrayEncodedValue)encodedValue);
74b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.ANNOTATION:
75b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableAnnotationEncodedValue.of((AnnotationEncodedValue)encodedValue);
76b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.NULL:
77b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableNullEncodedValue.INSTANCE;
78b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            case ValueType.BOOLEAN:
79b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return ImmutableBooleanEncodedValue.of((BooleanEncodedValue)encodedValue);
80b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            default:
81b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                Preconditions.checkArgument(false);
82b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                return null;
83b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver        }
84b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver    }
85b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
864ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver    @Nonnull
874ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver    public static EncodedValue defaultValueForType(String type) {
884ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver        switch (type.charAt(0)) {
894ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'Z':
90bddef6af3c39732ba0329c4a8e233f3858226f39Ben Gruver                return ImmutableBooleanEncodedValue.FALSE_VALUE;
914ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'B':
924ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableByteEncodedValue((byte)0);
934ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'S':
944ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableShortEncodedValue((short)0);
954ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'C':
964ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableCharEncodedValue((char)0);
974ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'I':
984ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableIntEncodedValue(0);
994ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'J':
1004ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableLongEncodedValue(0);
1014ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'F':
1024ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableFloatEncodedValue(0);
1034ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'D':
1044ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return new ImmutableDoubleEncodedValue(0);
1054ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case 'L':
1064ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            case '[':
1074ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                return ImmutableNullEncodedValue.INSTANCE;
1084ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver            default:
1094ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver                throw new ExceptionWithContext("Unrecognized type: %s", type);
1104ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver        }
1114ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver    }
1124ffbfa2e71ffdf6ecaa8429b19ce29daa28e9fc4Ben Gruver
113ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver    @Nullable
114ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver    public static ImmutableEncodedValue ofNullable(@Nullable EncodedValue encodedValue) {
115ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver        if (encodedValue == null) {
116ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver            return null;
117ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver        }
118ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver        return of(encodedValue);
119ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver    }
120ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver
121b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver    @Nonnull
12212b970ed4dfad768002335503e49c348ea0ed69bBen Gruver    public static ImmutableList<ImmutableEncodedValue> immutableListOf
12312b970ed4dfad768002335503e49c348ea0ed69bBen Gruver            (@Nullable Iterable<? extends EncodedValue> list) {
12422c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver        return CONVERTER.toList(list);
125b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver    }
126b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
12722c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver    private static final ImmutableConverter<ImmutableEncodedValue, EncodedValue> CONVERTER =
12822c3185bb7c8618437eabe6c597549e0989ec4e6Ben Gruver            new ImmutableConverter<ImmutableEncodedValue, EncodedValue>() {
129b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                @Override
130ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver                protected boolean isImmutable(@Nonnull EncodedValue item) {
131b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                    return item instanceof ImmutableEncodedValue;
132b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                }
133b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver
134ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver                @Nonnull
135b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                @Override
136ddf20219422e40a1e60268d8049093602d7bacf8Ben Gruver                protected ImmutableEncodedValue makeImmutable(@Nonnull EncodedValue item) {
137b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                    return of(item);
138b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver                }
139b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver            };
140b76e75c8bcc11d1e3f348166e2e9f83085154fc8Ben Gruver}
141