in c++/src/TypeImpl.cc [423:485]
std::unique_ptr<Type> convertType(const proto::Type& type, const proto::Footer& footer) {
std::unique_ptr<Type> ret;
switch (static_cast<int64_t>(type.kind())) {
case proto::Type_Kind_BOOLEAN:
case proto::Type_Kind_BYTE:
case proto::Type_Kind_SHORT:
case proto::Type_Kind_INT:
case proto::Type_Kind_LONG:
case proto::Type_Kind_FLOAT:
case proto::Type_Kind_DOUBLE:
case proto::Type_Kind_STRING:
case proto::Type_Kind_BINARY:
case proto::Type_Kind_TIMESTAMP:
case proto::Type_Kind_TIMESTAMP_INSTANT:
case proto::Type_Kind_DATE:
ret = std::make_unique<TypeImpl>(static_cast<TypeKind>(type.kind()));
break;
case proto::Type_Kind_CHAR:
case proto::Type_Kind_VARCHAR:
ret = std::make_unique<TypeImpl>(static_cast<TypeKind>(type.kind()), type.maximum_length());
break;
case proto::Type_Kind_DECIMAL:
ret = std::make_unique<TypeImpl>(DECIMAL, type.precision(), type.scale());
break;
case proto::Type_Kind_LIST:
case proto::Type_Kind_MAP:
case proto::Type_Kind_UNION: {
ret = std::make_unique<TypeImpl>(static_cast<TypeKind>(type.kind()));
if (type.kind() == proto::Type_Kind_LIST && type.subtypes_size() != 1)
throw ParseError("Illegal LIST type that doesn't contain one subtype");
if (type.kind() == proto::Type_Kind_MAP && type.subtypes_size() != 2)
throw ParseError("Illegal MAP type that doesn't contain two subtypes");
if (type.kind() == proto::Type_Kind_UNION && type.subtypes_size() == 0)
throw ParseError("Illegal UNION type that doesn't contain any subtypes");
for (int i = 0; i < type.subtypes_size(); ++i) {
ret->addUnionChild(convertType(footer.types(static_cast<int>(type.subtypes(i))), footer));
}
break;
}
case proto::Type_Kind_STRUCT: {
ret = std::make_unique<TypeImpl>(STRUCT);
if (type.subtypes_size() > type.field_names_size())
throw ParseError("Illegal STRUCT type that contains less field_names than subtypes");
for (int i = 0; i < type.subtypes_size(); ++i) {
ret->addStructField(
type.field_names(i),
convertType(footer.types(static_cast<int>(type.subtypes(i))), footer));
}
break;
}
default:
throw NotImplementedYet("Unknown type kind");
}
for (int i = 0; i < type.attributes_size(); ++i) {
const auto& attribute = type.attributes(i);
ret->setAttribute(attribute.key(), attribute.value());
}
return ret;
}