Repository: apache/arrow
File: cpp/src/parquet/arrow/schema.cc (C++)

Code before:
  // }
  //

  RETURN_NOT_OK(NodeToSchemaField(*key_value.field(0), current_levels, ctx,
                                  key_value_field, key_field));
  RETURN_NOT_OK(NodeToSchemaField(*key_value.field(1), current_levels, ctx,
                                  key_value_field, value_field));

  key_value_field->field = ::arrow::field(
      group.name(), ::arrow::struct_({key_field->field, value_field->field}),
      /*nullable=*/false, FieldIdMetadata(key_value.field_id()));
  key_value_field->level_info = current_levels;

  out->field = ::arrow::field(group.name(),
                              std::make_shared<::arrow::MapType>(key_value_field->field),
                              group.is_optional(), FieldIdMetadata(group.field_id()));
  out->level_info = current_levels;
  // At this point current levels contains the def level for this list,
  // we need to reset to the prior parent.
  out->level_info.repeated_ancestor_def_level = repeated_ancestor_def_level;
  return Status::OK();
}

Status ResolveList(const GroupNode& group, const Node& list_node,
                   LevelInfo current_levels, SchemaTreeContext* ctx, SchemaField* out) {
  auto check_two_level_list_repeated = [](const GroupNode& group) -> Status {
    // When it is repeated, the LIST-annotated 2-level structure can only serve as an
    // element within another LIST-annotated 2-level structure.
    if (group.is_repeated() &&
        (group.parent() == nullptr || !group.parent()->logical_type()->is_list())) {
      return Status::Invalid("LIST-annotated groups must not be repeated.");
    }
    return {};
  };

  SchemaField* child_field = &out->children[0];

  if (list_node.is_group()) {
    const auto& list_group = static_cast<const GroupNode&>(list_node);
    if (list_group.field_count() > 1) {
      // The inner type of the list should be a struct when there are multiple fields
      // in the repeated group
      RETURN_NOT_OK(check_two_level_list_repeated(group));
      return GroupToStruct(list_group, current_levels, ctx, out, child_field);
    }
    if (list_group.field_count() == 0) {
      return Status::Invalid("Group must have at least one child.");
    }

    if (list_group.logical_type()->is_none() && HasListElementName(list_group, group)) {
      // Rule 4 at https://github.com/apache/parquet-format/blob/master/LogicalTypes.md#backward-compatibility-rules

Review comment (suggestion):
```suggestion
  auto check_two_level_list_repetition = [](const GroupNode& group) -> Status {
```

Code after:
  // }
  //

  RETURN_NOT_OK(NodeToSchemaField(*key_value.field(0), current_levels, ctx,
                                  key_value_field, key_field));
  RETURN_NOT_OK(NodeToSchemaField(*key_value.field(1), current_levels, ctx,
                                  key_value_field, value_field));

  key_value_field->field = ::arrow::field(
      group.name(), ::arrow::struct_({key_field->field, value_field->field}),
      /*nullable=*/false, FieldIdMetadata(key_value.field_id()));
  key_value_field->level_info = current_levels;

  out->field = ::arrow::field(group.name(),
                              std::make_shared<::arrow::MapType>(key_value_field->field),
                              group.is_optional(), FieldIdMetadata(group.field_id()));
  out->level_info = current_levels;
  // At this point current levels contains the def level for this list,
  // we need to reset to the prior parent.
  out->level_info.repeated_ancestor_def_level = repeated_ancestor_def_level;
  return Status::OK();
}

Status ResolveList(const GroupNode& group, LevelInfo current_levels,
                   SchemaTreeContext* ctx, SchemaField* out) {
  auto check_two_level_list_repetition = [](const GroupNode& group) -> Status {
    // When it is repeated, the LIST-annotated 2-level structure can only serve as an
    // element within another LIST-annotated 2-level structure.
    if (group.is_repeated() &&
        (group.parent() == nullptr || !group.parent()->logical_type()->is_list())) {
      return Status::Invalid("LIST-annotated groups must not be repeated.");
    }
    return {};
  };

  SchemaField* child_field = &out->children[0];
  const Node& list_node = *group.field(0);
  if (!list_node.is_repeated()) {
    return Status::Invalid(
        "Non-repeated nodes in a LIST-annotated group are not supported.");
  }

  if (list_node.is_group()) {
    const auto& list_group = static_cast<const GroupNode&>(list_node);
    if (list_group.field_count() > 1) {
      // The inner type of the list should be a struct when there are multiple fields
      // in the repeated group
      RETURN_NOT_OK(check_two_level_list_repetition(group));
      return GroupToStruct(list_group, current_levels, ctx, out, child_field);
    }
    if (list_group.field_count() == 0) {