1674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen/*
2674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * Copyright 2003 The Apache Software Foundation
3674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
4674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *  Licensed under the Apache License, Version 2.0 (the "License");
5674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * you may not use this file except in compliance with the License.
6674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * You may obtain a copy of the License at
7674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
8674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *      http://www.apache.org/licenses/LICENSE-2.0
9674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *
10674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen *  Unless required by applicable law or agreed to in writing, software
11674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * distributed under the License is distributed on an "AS IS" BASIS,
12674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * See the License for the specific language governing permissions and
14674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen * limitations under the License.
15674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen */
16674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpackage org.mockito.cglib.transform.impl;
17674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
18674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport java.util.*;
19674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
20674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Attribute;
21674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Label;
22674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.asm.Type;
23674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.cglib.core.*;
24674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenimport org.mockito.cglib.transform.*;
25674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
26674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogenpublic class FieldProviderTransformer extends ClassEmitterTransformer {
27674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
28674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final String FIELD_NAMES = "CGLIB$FIELD_NAMES";
29674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final String FIELD_TYPES = "CGLIB$FIELD_TYPES";
30674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
31674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Type FIELD_PROVIDER =
32674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseType("org.mockito.cglib.transform.impl.FieldProvider");
33674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Type ILLEGAL_ARGUMENT_EXCEPTION =
34674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseType("IllegalArgumentException");
35674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Signature PROVIDER_GET =
36674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseSignature("Object getField(String)");
37674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Signature PROVIDER_SET =
38674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseSignature("void setField(String, Object)");
39674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Signature PROVIDER_SET_BY_INDEX =
40674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseSignature("void setField(int, Object)");
41674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Signature PROVIDER_GET_BY_INDEX =
42674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseSignature("Object getField(int)");
43674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Signature PROVIDER_GET_TYPES =
44674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseSignature("Class[] getFieldTypes()");
45674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private static final Signature PROVIDER_GET_NAMES =
46674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen      TypeUtils.parseSignature("String[] getFieldNames()");
47674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
48674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private int access;
49674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private Map fields;
50674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
51674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void begin_class(int version, int access, String className, Type superType, Type[] interfaces, String sourceFile) {
52674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (!TypeUtils.isAbstract(access)) {
53674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            interfaces = TypeUtils.add(interfaces, FIELD_PROVIDER);
54674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
55674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        this.access = access;
56674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        fields = new HashMap();
57674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        super.begin_class(version, access, className, superType, interfaces, sourceFile);
58674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
59674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
60674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void declare_field(int access, String name, Type type, Object value) {
61674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        super.declare_field(access, name, type, value);
62674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
63674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (!TypeUtils.isStatic(access)) {
64674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            fields.put(name, type);
65674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
66674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
67674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
68674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    public void end_class() {
69674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        if (!TypeUtils.isInterface(access)) {
70674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            try {
71674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                generate();
72674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            } catch (RuntimeException e) {
73674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                throw e;
74674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            } catch (Exception e) {
75674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                throw new CodeGenerationException(e);
76674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
77674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
78674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        super.end_class();
79674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
80674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
81674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void generate() throws Exception {
82674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final String[] names = (String[])fields.keySet().toArray(new String[fields.size()]);
83674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
84674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        int indexes[] = new int[names.length];
85674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for (int i = 0; i < indexes.length; i++) {
86674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            indexes[i] = i;
87674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
88674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
89674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        super.declare_field(Constants.PRIVATE_FINAL_STATIC, FIELD_NAMES, Constants.TYPE_STRING_ARRAY, null);
90674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        super.declare_field(Constants.PRIVATE_FINAL_STATIC, FIELD_TYPES, Constants.TYPE_CLASS_ARRAY, null);
91674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
92674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        // use separate methods here because each process switch inner class needs a final CodeEmitter
93674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        initFieldProvider(names);
94674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        getNames();
95674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        getTypes();
96674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        getField(names);
97674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        setField(names);
98674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        setByIndex(names, indexes);
99674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        getByIndex(names, indexes);
100674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
101674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
102674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void initFieldProvider(String[] names) {
103674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        CodeEmitter e = getStaticHook();
104674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        EmitUtils.push_object(e, names);
105674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.putstatic(getClassType(), FIELD_NAMES, Constants.TYPE_STRING_ARRAY);
106674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
107674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.push(names.length);
108674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.newarray(Constants.TYPE_CLASS);
109674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.dup();
110674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        for(int i = 0; i < names.length; i++ ){
111674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            e.dup();
112674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            e.push(i);
113674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            Type type = (Type)fields.get(names[i]);
114674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            EmitUtils.load_class(e, type);
115674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            e.aastore();
116674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        }
117674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.putstatic(getClassType(), FIELD_TYPES, Constants.TYPE_CLASS_ARRAY);
118674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
119674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
120674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void getNames() {
121674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_NAMES, null);
122674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.getstatic(getClassType(), FIELD_NAMES, Constants.TYPE_STRING_ARRAY);
123674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.return_value();
124674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.end_method();
125674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
126674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
127674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void getTypes() {
128674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_TYPES, null);
129674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.getstatic(getClassType(), FIELD_TYPES, Constants.TYPE_CLASS_ARRAY);
130674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.return_value();
131674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.end_method();
132674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
133674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
134674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void setByIndex(final String[] names, final int[] indexes) throws Exception {
135674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_SET_BY_INDEX, null);
136674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_this();
137674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_arg(1);
138674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_arg(0);
139674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.process_switch(indexes, new ProcessSwitchCallback() {
140674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processCase(int key, Label end) throws Exception {
141674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                Type type = (Type)fields.get(names[key]);
142674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.unbox(type);
143674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.putfield(names[key]);
144674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.return_value();
145674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
146674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processDefault() throws Exception {
147674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index");
148674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
149674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        });
150674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.end_method();
151674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
152674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
153674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void getByIndex(final String[] names, final int[] indexes) throws Exception {
154674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final CodeEmitter e = super.begin_method(Constants.ACC_PUBLIC, PROVIDER_GET_BY_INDEX, null);
155674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_this();
156674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_arg(0);
157674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.process_switch(indexes, new ProcessSwitchCallback() {
158674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processCase(int key, Label end) throws Exception {
159674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                Type type = (Type)fields.get(names[key]);
160674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.getfield(names[key]);
161674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.box(type);
162674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.return_value();
163674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
164674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processDefault() throws Exception {
165674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field index");
166674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
167674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        });
168674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.end_method();
169674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
170674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
171674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // TODO: if this is used to enhance class files SWITCH_STYLE_TRIE should be used
172674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    // to avoid JVM hashcode implementation incompatibilities
173674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void getField(String[] names) throws Exception {
174674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_GET, null);
175674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_this();
176674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_arg(0);
177674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
178674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processCase(Object key, Label end) {
179674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                Type type = (Type)fields.get(key);
180674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.getfield((String)key);
181674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.box(type);
182674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.return_value();
183674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
184674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processDefault() {
185674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name");
186674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
187674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        });
188674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.end_method();
189674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
190674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen
191674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    private void setField(String[] names) throws Exception {
192674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        final CodeEmitter e = begin_method(Constants.ACC_PUBLIC, PROVIDER_SET, null);
193674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_this();
194674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_arg(1);
195674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.load_arg(0);
196674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        EmitUtils.string_switch(e, names, Constants.SWITCH_STYLE_HASH, new ObjectSwitchCallback() {
197674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processCase(Object key, Label end) {
198674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                Type type = (Type)fields.get(key);
199674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.unbox(type);
200674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.putfield((String)key);
201674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.return_value();
202674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
203674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            public void processDefault() {
204674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen                e.throw_exception(ILLEGAL_ARGUMENT_EXCEPTION, "Unknown field name");
205674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen            }
206674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        });
207674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen        e.end_method();
208674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen    }
209674060f01e9090cd21b3c5656cc3204912ad17a6Jon Boekenoogen}
210