public static TypeDescription convert(Schema schema) {
    final TypeDescription root = TypeDescription.createStruct();
    final Types.StructType schemaRoot = schema.asStruct();
    for (Types.NestedField field : schemaRoot.asStructType().fields()) {
      TypeDescription orcColumnType = convert(field.fieldId(), field.type(), field.isRequired());
      root.addField(field.name(), orcColumnType);
    }
    return root;
  }
@Test
  public void testRoundtripConversionNested() {
    Types.StructType leafStructType =
        Types.StructType.of(
            optional(6, "leafLongCol", Types.LongType.get()),
            optional(7, "leafBinaryCol", Types.BinaryType.get()));
    Types.StructType nestedStructType =
        Types.StructType.of(
            optional(4, "longCol", Types.LongType.get()),
            optional(5, "leafStructCol", leafStructType));
    Types.StructType structPrimTypeForList =
        Types.StructType.of(
            optional(506, "leafLongCol", Types.LongType.get()),
            optional(507, "leafBinaryCol", Types.BinaryType.get()));
    Types.StructType leafStructTypeForList =
        Types.StructType.of(
            optional(516, "leafLongCol", Types.LongType.get()),
            optional(517, "leafBinaryCol", Types.BinaryType.get()));
    Types.StructType nestedStructTypeForList =
        Types.StructType.of(
            optional(504, "longCol", Types.LongType.get()),
            optional(505, "leafStructCol", leafStructTypeForList));
    Types.StructType structPrimTypeForMap =
        Types.StructType.of(
            optional(606, "leafLongCol", Types.LongType.get()),
            optional(607, "leafBinaryCol", Types.BinaryType.get()));
    Types.StructType leafStructTypeForMap =
        Types.StructType.of(
            optional(616, "leafLongCol", Types.LongType.get()),
            optional(617, "leafBinaryCol", Types.BinaryType.get()));
    Types.StructType nestedStructTypeForMap =
        Types.StructType.of(
            optional(604, "longCol", Types.LongType.get()),
            optional(605, "leafStructCol", leafStructTypeForMap));
    Types.StructType leafStructTypeForStruct =
        Types.StructType.of(
            optional(716, "leafLongCol", Types.LongType.get()),
            optional(717, "leafBinaryCol", Types.BinaryType.get()));
    Types.StructType nestedStructTypeForStruct =
        Types.StructType.of(
            optional(704, "longCol", Types.LongType.get()),
            optional(705, "leafStructCol", leafStructTypeForStruct));
    // all fields in expected iceberg schema will be optional since we don't have a column mapping
    Schema expectedSchema =
        new Schema(
            optional(1, "intCol", Types.IntegerType.get()),
            optional(2, "longCol", Types.LongType.get()),
            optional(3, "nestedStructCol", nestedStructType),
            optional(8, "intCol3", Types.IntegerType.get()),
            optional(9, "doubleCol", Types.DoubleType.get()),
            required(10, "uuidCol", Types.UUIDType.get()),
            optional(20, "booleanCol", Types.BooleanType.get()),
            optional(21, "fixedCol", Types.FixedType.ofLength(4096)),
            required(22, "binaryCol", Types.BinaryType.get()),
            required(23, "stringCol", Types.StringType.get()),
            required(24, "decimalCol", Types.DecimalType.of(15, 3)),
            required(25, "floatCol", Types.FloatType.get()),
            optional(30, "dateCol", Types.DateType.get()),
            required(32, "timeCol", Types.TimeType.get()),
            required(34, "timestampCol", Types.TimestampType.withZone()),
            required(35, "listPrimCol", Types.ListType.ofRequired(135, Types.LongType.get())),
            required(36, "listPrimNestCol", Types.ListType.ofRequired(136, structPrimTypeForList)),
            required(37, "listNestedCol", Types.ListType.ofRequired(137, nestedStructTypeForList)),
            optional(
                38,
                "mapPrimCol",
                Types.MapType.ofRequired(
                    138, 238, Types.StringType.get(), Types.FixedType.ofLength(4096))),
            required(
                39,
                "mapPrimNestCol",
                Types.MapType.ofRequired(139, 239, Types.StringType.get(), structPrimTypeForMap)),
            required(
                40,
                "mapNestedCol",
                Types.MapType.ofRequired(140, 240, Types.StringType.get(), nestedStructTypeForMap)),
            required(
                41,
                "structListNestCol",
                Types.ListType.ofRequired(
                    241,
                    Types.StructType.of(
                        optional(816, "leafLongCol", Types.LongType.get()),
                        optional(817, "leafBinaryCol", Types.BinaryType.get())))),
            required(
                42,
                "structMapNestCol",
                Types.MapType.ofRequired(
                    242,
                    342,
                    Types.StringType.get(),
                    Types.StructType.of(
                        optional(916, "leafLongCol", Types.LongType.get()),
                        optional(917, "leafBinaryCol", Types.BinaryType.get())))),
            required(
                43,
                "structStructNestCol",
                Types.StructType.of(
                    required(
                        243,
                        "innerStructNest",
                        Types.StructType.of(
                            optional(1016, "leafLongCol", Types.LongType.get()),
                            optional(1017, "leafBinaryCol", Types.BinaryType.get()))))),
            required(
                44,
                "structStructComplexNestCol",
                Types.StructType.of(
                    required(
                        244,
                        "innerStructNest",
                        Types.StructType.of(
                            optional(1116, "leafLongCol", Types.LongType.get()),
                            optional(
                                1117,
                                "leftMapOfListStructCol",
                                Types.MapType.ofRequired(
                                    1150,
                                    1151,
                                    Types.StringType.get(),
                                    Types.ListType.ofRequired(
                                        1250, nestedStructTypeForStruct))))))));
    TypeDescription orcSchema = ORCSchemaUtil.convert(expectedSchema);
    assertThat(ORCSchemaUtil.convert(orcSchema).asStruct()).isEqualTo(expectedSchema.asStruct());
  }