1 /*
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements.  See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License.  You may obtain a copy of the License at
8  *
9  *    http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 
18 import org.apache.arrow.vector.complex.MapVector;
19 import org.apache.arrow.vector.complex.impl.UnionMapReader;
20 import org.apache.arrow.vector.complex.impl.UnionMapWriter;
21 import org.apache.arrow.vector.complex.reader.FieldReader;
22 import org.apache.arrow.vector.complex.writer.FieldWriter;
23 
24 <@pp.dropOutputFile />
25 <@pp.changeOutputFile name="/org/apache/arrow/vector/complex/impl/ComplexCopier.java" />
26 
27 
28 <#include "/@includes/license.ftl" />
29 
30 package org.apache.arrow.vector.complex.impl;
31 
32 <#include "/@includes/vv_imports.ftl" />
33 
34 /*
35  * This class is generated using freemarker and the ${.template_name} template.
36  */
37 @SuppressWarnings("unused")
38 public class ComplexCopier {
39 
40   /**
41    * Do a deep copy of the value in input into output
42    * @param input field to read from
43    * @param output field to write to
44    */
copy(FieldReader input, FieldWriter output)45   public static void copy(FieldReader input, FieldWriter output) {
46     writeValue(input, output);
47   }
48 
writeValue(FieldReader reader, FieldWriter writer)49   private static void writeValue(FieldReader reader, FieldWriter writer) {
50     final MinorType mt = reader.getMinorType();
51 
52       switch (mt) {
53 
54       case LIST:
55       case FIXED_SIZE_LIST:
56         if (reader.isSet()) {
57           writer.startList();
58           while (reader.next()) {
59             FieldReader childReader = reader.reader();
60             FieldWriter childWriter = getListWriterForReader(childReader, writer);
61             if (childReader.isSet()) {
62               writeValue(childReader, childWriter);
63             } else {
64               childWriter.writeNull();
65             }
66           }
67           writer.endList();
68         } else {
69           writer.writeNull();
70         }
71         break;
72       case MAP:
73         if (reader.isSet()) {
74           UnionMapWriter mapWriter = (UnionMapWriter) writer;
75           UnionMapReader mapReader = (UnionMapReader) reader;
76 
77           mapWriter.startMap();
78           while (mapReader.next()) {
79             FieldReader structReader = reader.reader();
80             UnionMapWriter structWriter = (UnionMapWriter) writer.struct();
81             if (structReader.isSet()) {
82               mapWriter.startEntry();
83               writeValue(mapReader.key(), getStructWriterForReader(mapReader.key(), structWriter.key(), MapVector.KEY_NAME));
84               writeValue(mapReader.value(), getStructWriterForReader(mapReader.value(), structWriter.value(), MapVector.VALUE_NAME));
85               mapWriter.endEntry();
86             } else {
87               structWriter.writeNull();
88             }
89           }
90           mapWriter.endMap();
91         } else {
92           writer.writeNull();
93         }
94         break;
95       case STRUCT:
96         if (reader.isSet()) {
97           writer.start();
98           for(String name : reader){
99             FieldReader childReader = reader.reader(name);
100             FieldWriter childWriter = getStructWriterForReader(childReader, writer, name);
101             if(childReader.isSet()){
102               writeValue(childReader, childWriter);
103             } else {
104               childWriter.writeNull();
105             }
106           }
107           writer.end();
108         } else {
109           writer.writeNull();
110         }
111         break;
112   <#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
113   <#assign fields = minor.fields!type.fields />
114   <#assign uncappedName = name?uncap_first/>
115 
116   <#if !minor.typeParams?? || minor.class?starts_with("Decimal") >
117 
118       case ${name?upper_case}:
119         if (reader.isSet()) {
120           Nullable${name}Holder ${uncappedName}Holder = new Nullable${name}Holder();
121           reader.read(${uncappedName}Holder);
122           if (${uncappedName}Holder.isSet == 1) {
123             writer.write${name}(<#list fields as field>${uncappedName}Holder.${field.name}<#if field_has_next>, </#if></#list><#if minor.class == "Decimal">, new ArrowType.Decimal(decimalHolder.precision, decimalHolder.scale)</#if>);
124           }
125         } else {
126           writer.writeNull();
127         }
128         break;
129 
130   </#if>
131   </#list></#list>
132       }
133  }
134 
getStructWriterForReader(FieldReader reader, StructWriter writer, String name)135   private static FieldWriter getStructWriterForReader(FieldReader reader, StructWriter writer, String name) {
136     switch (reader.getMinorType()) {
137     <#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
138     <#assign fields = minor.fields!type.fields />
139     <#assign uncappedName = name?uncap_first/>
140     <#if !minor.typeParams??>
141     case ${name?upper_case}:
142       return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}</#if>(name);
143     </#if>
144     <#if minor.class == "Decimal">
145     case ${name?upper_case}:
146       if (reader.getField().getType() instanceof ArrowType.Decimal) {
147         ArrowType.Decimal type = (ArrowType.Decimal) reader.getField().getType();
148         return (FieldWriter) writer.${uncappedName}(name, type.getScale(), type.getPrecision());
149       } else {
150         return (FieldWriter) writer.${uncappedName}(name);
151       }
152     </#if>
153     </#list></#list>
154     case STRUCT:
155       return (FieldWriter) writer.struct(name);
156     case FIXED_SIZE_LIST:
157     case LIST:
158     case MAP:
159       return (FieldWriter) writer.list(name);
160     default:
161       throw new UnsupportedOperationException(reader.getMinorType().toString());
162     }
163   }
164 
165   private static FieldWriter getListWriterForReader(FieldReader reader, ListWriter writer) {
166     switch (reader.getMinorType()) {
167     <#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
168     <#assign fields = minor.fields!type.fields />
169     <#assign uncappedName = name?uncap_first/>
170     <#if !minor.typeParams?? || minor.class?starts_with("Decimal") >
171     case ${name?upper_case}:
172     return (FieldWriter) writer.<#if name == "Int">integer<#else>${uncappedName}</#if>();
173     </#if>
174     </#list></#list>
175     case STRUCT:
176       return (FieldWriter) writer.struct();
177     case FIXED_SIZE_LIST:
178     case LIST:
179     case MAP:
180     case NULL:
181       return (FieldWriter) writer.list();
182     default:
183       throw new UnsupportedOperationException(reader.getMinorType().toString());
184     }
185   }
186 }
187