/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import org.apache.arrow.vector.types.pojo.ArrowType.Null;
import org.apache.arrow.vector.types.pojo.Field;

<@pp.dropOutputFile />
<@pp.changeOutputFile name="/org/apache/arrow/vector/complex/impl/NullReader.java" />


<#include "/@includes/license.ftl" />

package org.apache.arrow.vector.complex.impl;

<#include "/@includes/vv_imports.ftl" />

/**
 * Source code generated using FreeMarker template ${.template_name}
 */
@SuppressWarnings("unused")
public class NullReader extends AbstractBaseReader implements FieldReader{

  public static final NullReader INSTANCE = new NullReader();
  public static final NullReader EMPTY_LIST_INSTANCE = new NullReader(MinorType.NULL);
  public static final NullReader EMPTY_STRUCT_INSTANCE = new NullReader(MinorType.STRUCT);
  private MinorType type;

  private NullReader(){
    super();
    type = MinorType.NULL;
  }

  private NullReader(MinorType type){
    super();
    this.type = type;
  }

  @Override
  public MinorType getMinorType() {
    return type;
  }

  @Override
  public Field getField() {
    return new Field("", FieldType.nullable(new Null()), null);
  }

  public void copyAsValue(StructWriter writer) {}

  public void copyAsValue(ListWriter writer) {}

  public void copyAsValue(UnionWriter writer) {}

  <#list vv.types as type><#list type.minor as minor><#assign name = minor.class?cap_first />
  public void read(${name}Holder holder){
    throw new UnsupportedOperationException("NullReader cannot write into non-nullable holder");
  }

  public void read(Nullable${name}Holder holder){
    holder.isSet = 0;
  }

  public void read(int arrayIndex, ${name}Holder holder){
    throw new ArrayIndexOutOfBoundsException();
  }

  public void copyAsValue(${minor.class}Writer writer){}
  public void copyAsField(String name, ${minor.class}Writer writer){}

  public void read(int arrayIndex, Nullable${name}Holder holder){
    throw new ArrayIndexOutOfBoundsException();
  }
  </#list></#list>

  public void copyAsValue(StructWriter writer, ExtensionTypeWriterFactory writerFactory){}
  public void read(ExtensionHolder holder) {
    holder.isSet = 0;
  }

  public int size(){
    return 0;
  }

  public boolean isSet(){
    return false;
  }

  public boolean next(){
    return false;
  }

  public RepeatedStructReader struct(){
    return this;
  }

  public RepeatedListReader list(){
    return this;
  }

  public StructReader struct(String name){
    return this;
  }

  public ListReader list(String name){
    return this;
  }

  public FieldReader reader(String name){
    return this;
  }

  public FieldReader reader(){
    return this;
  }

  private void fail(String name){
    throw new IllegalArgumentException(String.format("You tried to read a %s type when you are using a ValueReader of type %s.", name, this.getClass().getSimpleName()));
  }

  <#list ["Object", "BigDecimal", "Short", "Integer", "Long", "Boolean",
          "LocalDateTime", "Duration", "Period", "Double", "Float",
          "Character", "Text", "String", "Byte", "byte[]", "PeriodDuration"] as friendlyType>
  <#assign safeType=friendlyType />
  <#if safeType=="byte[]"><#assign safeType="ByteArray" /></#if>

  public ${friendlyType} read${safeType}(int arrayIndex){
    return null;
  }

  public ${friendlyType} read${safeType}(){
    return null;
  }
  </#list>

}
