// Path: metacat-common/src/main/java/com/netflix/metacat/common/type/MapType.java
// @Getter
// @EqualsAndHashCode(callSuper = true)
// public class MapType extends AbstractType implements ParametricType {
//     /**
//      * default.
//      */
//     public static final MapType MAP = new MapType(BaseType.UNKNOWN, BaseType.UNKNOWN);
// 
//     private final Type keyType;
//     private final Type valueType;
// 
//     /**
//      * Constructor.
//      *
//      * @param keyType   keytype
//      * @param valueType valuetype
//      */
//     public MapType(final Type keyType, final Type valueType) {
//         super(TypeUtils.parameterizedTypeSignature(TypeEnum.MAP,
//             keyType.getTypeSignature(), valueType.getTypeSignature()));
//         this.keyType = keyType;
//         this.valueType = valueType;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getDisplayName() {
//         return "map<" + keyType.getDisplayName()
//             + ", " + valueType.getDisplayName() + ">";
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public List<Type> getParameters() {
//         return ImmutableList.of(getKeyType(), getValueType());
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public TypeEnum getBaseType() {
//         return TypeEnum.MAP;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public Type createType(final List<Type> types, final List<Object> literals) {
//         Preconditions.checkArgument(types.size() == 2, "Expected two types");
//         Preconditions.checkArgument(literals.isEmpty(), "Unexpected literals: %s", literals);
//         return new MapType(types.get(0), types.get(1));
//     }
// }


import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.netflix.metacat.common.server.connectors.ConnectorTypeConverter;
import com.netflix.metacat.common.server.connectors.model.FieldInfo;
import com.netflix.metacat.common.type.BaseType;
import com.netflix.metacat.common.type.CharType;
import com.netflix.metacat.common.type.DecimalType;
import com.netflix.metacat.common.type.MapType;
import com.netflix.metacat.common.type.ParametricType;
import com.netflix.metacat.common.type.RowType;
import com.netflix.metacat.common.type.Type;
import com.netflix.metacat.common.type.TypeEnum;
import com.netflix.metacat.common.type.TypeRegistry;
import com.netflix.metacat.common.type.TypeSignature;
import com.netflix.metacat.common.type.TypeUtils;
import com.netflix.metacat.common.type.VarcharType;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hive.serde.serdeConstants;
import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.MapObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
import org.apache.hadoop.hive.serde2.objectinspector.StandardStructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructField;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.typeinfo.CharTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.DecimalTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils;
import org.apache.hadoop.hive.serde2.typeinfo.VarcharTypeInfo;
import org.apache.iceberg.PartitionField;
import org.apache.iceberg.Schema;
import org.apache.iceberg.types.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
                return serdeConstants.BINARY_TYPE_NAME;
            case DECIMAL:
                final Types.DecimalType decimalType = (Types.DecimalType) type;
                return String.format("decimal(%s,%s)", decimalType.precision(), decimalType.scale());
            case STRUCT:
                final Types.StructType structType = type.asStructType();
                final String nameToType = (String) structType.fields().stream().map((f) -> {
                    return String.format("%s:%s", f.name(), fromIcebergToHiveType(f.type()));
                }).collect(Collectors.joining(","));
                return String.format("struct<%s>", nameToType);
            case LIST:
                final Types.ListType listType = type.asListType();
                return String.format("array<%s>", fromIcebergToHiveType(listType.elementType()));
            case MAP:
                final Types.MapType mapType = type.asMapType();
                return String.format("map<%s,%s>", fromIcebergToHiveType(mapType.keyType()),
                    fromIcebergToHiveType(mapType.valueType()));
            default:
                throw new UnsupportedOperationException(type + " is not supported");
        }
    }

    @Override
    public String fromMetacatType(final Type type) {
        if (HiveTypeMapping.getCANONICAL_TO_HIVE().containsKey(type)) {
            return HiveTypeMapping.getCANONICAL_TO_HIVE().get(type);
        }
        if (type instanceof DecimalType | type instanceof CharType | type instanceof VarcharType) {
            return type.getDisplayName();
        } else if (type.getTypeSignature().getBase().equals(TypeEnum.MAP)) {
// Path: metacat-common/src/main/java/com/netflix/metacat/common/type/MapType.java
// @Getter
// @EqualsAndHashCode(callSuper = true)
// public class MapType extends AbstractType implements ParametricType {
//     /**
//      * default.
//      */
//     public static final MapType MAP = new MapType(BaseType.UNKNOWN, BaseType.UNKNOWN);
// 
//     private final Type keyType;
//     private final Type valueType;
// 
//     /**
//      * Constructor.
//      *
//      * @param keyType   keytype
//      * @param valueType valuetype
//      */
//     public MapType(final Type keyType, final Type valueType) {
//         super(TypeUtils.parameterizedTypeSignature(TypeEnum.MAP,
//             keyType.getTypeSignature(), valueType.getTypeSignature()));
//         this.keyType = keyType;
//         this.valueType = valueType;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public String getDisplayName() {
//         return "map<" + keyType.getDisplayName()
//             + ", " + valueType.getDisplayName() + ">";
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public List<Type> getParameters() {
//         return ImmutableList.of(getKeyType(), getValueType());
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public TypeEnum getBaseType() {
//         return TypeEnum.MAP;
//     }
// 
//     /**
//      * {@inheritDoc}
//      */
//     @Override
//     public Type createType(final List<Type> types, final List<Object> literals) {
//         Preconditions.checkArgument(types.size() == 2, "Expected two types");
//         Preconditions.checkArgument(literals.isEmpty(), "Unexpected literals: %s", literals);
//         return new MapType(types.get(0), types.get(1));
//     }
// }


// Path: metacat-connector-hive/src/main/java/com/netflix/metacat/connector/hive/converters/HiveTypeConverter.java
import com.google.common.collect.ImmutableList;
import com.google.common.collect.Lists;
import com.netflix.metacat.common.server.connectors.ConnectorTypeConverter;
import com.netflix.metacat.common.server.connectors.model.FieldInfo;
import com.netflix.metacat.common.type.BaseType;
import com.netflix.metacat.common.type.CharType;
import com.netflix.metacat.common.type.DecimalType;
import com.netflix.metacat.common.type.MapType;
import com.netflix.metacat.common.type.ParametricType;
import com.netflix.metacat.common.type.RowType;
import com.netflix.metacat.common.type.Type;
import com.netflix.metacat.common.type.TypeEnum;
import com.netflix.metacat.common.type.TypeRegistry;
import com.netflix.metacat.common.type.TypeSignature;
import com.netflix.metacat.common.type.TypeUtils;
import com.netflix.metacat.common.type.VarcharType;
import lombok.extern.slf4j.Slf4j;
import org.apache.hadoop.hive.serde.serdeConstants;
import org.apache.hadoop.hive.serde2.objectinspector.ListObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.MapObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.ObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.PrimitiveObjectInspector.PrimitiveCategory;
import org.apache.hadoop.hive.serde2.objectinspector.StandardStructObjectInspector;
import org.apache.hadoop.hive.serde2.objectinspector.StructField;
import org.apache.hadoop.hive.serde2.objectinspector.StructObjectInspector;
import org.apache.hadoop.hive.serde2.typeinfo.CharTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.DecimalTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.StructTypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfo;
import org.apache.hadoop.hive.serde2.typeinfo.TypeInfoUtils;
import org.apache.hadoop.hive.serde2.typeinfo.VarcharTypeInfo;
import org.apache.iceberg.PartitionField;
import org.apache.iceberg.Schema;
import org.apache.iceberg.types.Types;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;

                return serdeConstants.BINARY_TYPE_NAME;
            case DECIMAL:
                final Types.DecimalType decimalType = (Types.DecimalType) type;
                return String.format("decimal(%s,%s)", decimalType.precision(), decimalType.scale());
            case STRUCT:
                final Types.StructType structType = type.asStructType();
                final String nameToType = (String) structType.fields().stream().map((f) -> {
                    return String.format("%s:%s", f.name(), fromIcebergToHiveType(f.type()));
                }).collect(Collectors.joining(","));
                return String.format("struct<%s>", nameToType);
            case LIST:
                final Types.ListType listType = type.asListType();
                return String.format("array<%s>", fromIcebergToHiveType(listType.elementType()));
            case MAP:
                final Types.MapType mapType = type.asMapType();
                return String.format("map<%s,%s>", fromIcebergToHiveType(mapType.keyType()),
                    fromIcebergToHiveType(mapType.valueType()));
            default:
                throw new UnsupportedOperationException(type + " is not supported");
        }
    }

    @Override
    public String fromMetacatType(final Type type) {
        if (HiveTypeMapping.getCANONICAL_TO_HIVE().containsKey(type)) {
            return HiveTypeMapping.getCANONICAL_TO_HIVE().get(type);
        }
        if (type instanceof DecimalType | type instanceof CharType | type instanceof VarcharType) {
            return type.getDisplayName();
        } else if (type.getTypeSignature().getBase().equals(TypeEnum.MAP)) {
            final MapType mapType = (MapType) type;