| 189 | } |
| 190 | |
| 191 | Status VisitField(const std::shared_ptr<Field>& field, FieldPosition field_pos) { |
| 192 | writer_->StartObject(); |
| 193 | |
| 194 | writer_->Key("name"); |
| 195 | writer_->String(field->name().c_str()); |
| 196 | |
| 197 | writer_->Key("nullable"); |
| 198 | writer_->Bool(field->nullable()); |
| 199 | |
| 200 | const DataType* type = field->type().get(); |
| 201 | std::vector<std::pair<std::string, std::string>> additional_metadata; |
| 202 | if (type->id() == Type::EXTENSION) { |
| 203 | const auto& ext_type = checked_cast<const ExtensionType&>(*type); |
| 204 | type = ext_type.storage_type().get(); |
| 205 | additional_metadata.emplace_back(kExtensionTypeKeyName, ext_type.extension_name()); |
| 206 | additional_metadata.emplace_back(kExtensionMetadataKeyName, ext_type.Serialize()); |
| 207 | } |
| 208 | |
| 209 | // Visit the type |
| 210 | writer_->Key("type"); |
| 211 | writer_->StartObject(); |
| 212 | RETURN_NOT_OK(VisitType(*type)); |
| 213 | writer_->EndObject(); |
| 214 | |
| 215 | if (type->id() == Type::DICTIONARY) { |
| 216 | const auto& dict_type = checked_cast<const DictionaryType&>(*type); |
| 217 | // Ensure we visit child fields first so that, in the case of nested |
| 218 | // dictionaries, inner dictionaries get a smaller id than outer dictionaries. |
| 219 | RETURN_NOT_OK(WriteChildren(dict_type.value_type()->fields(), field_pos)); |
| 220 | ARROW_ASSIGN_OR_RAISE(const int64_t dictionary_id, |
| 221 | mapper_.GetFieldId(field_pos.path())); |
| 222 | RETURN_NOT_OK(WriteDictionaryMetadata(dictionary_id, dict_type)); |
| 223 | } else { |
| 224 | RETURN_NOT_OK(WriteChildren(type->fields(), field_pos)); |
| 225 | } |
| 226 | |
| 227 | WriteKeyValueMetadata(field->metadata(), additional_metadata); |
| 228 | writer_->EndObject(); |
| 229 | |
| 230 | return Status::OK(); |
| 231 | } |
| 232 | |
| 233 | Status VisitType(const DataType& type); |
| 234 |
nothing calls this directly
no test coverage detected