in compiler/cpp/src/thrift/generate/t_swift_generator.cc [1128:1326]
void t_swift_generator::generate_swift_struct_reader(ostream& out,
t_struct* tstruct,
bool is_private) {
if (!gen_cocoa_) {
/** Swift 3 case */
string visibility = is_private ? "fileprivate" : "public";
indent(out) << visibility << " static func read(from proto: TProtocol) throws -> "
<< tstruct->get_name();
block_open(out);
indent(out) << "_ = try proto.readStructBegin()" << '\n';
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
bool optional = field_is_optional(*f_iter);
indent(out) << "var " << maybe_escape_identifier((*f_iter)->get_name()) << ": "
<< type_name((*f_iter)->get_type(), optional, !optional) << '\n';
}
out << '\n';
// Loop over reading in fields
indent(out) << "fields: while true";
block_open(out);
out << '\n';
indent(out) << "let (_, fieldType, fieldID) = try proto.readFieldBegin()" << '\n' << '\n';
indent(out) << "switch (fieldID, fieldType)";
block_open(out);
indent(out) << "case (_, .stop): break fields" << '\n';
// Generate deserialization code for known cases
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
indent(out) << "case (" << (*f_iter)->get_key() << ", " << type_to_enum((*f_iter)->get_type()) << "):";
string padding = "";
t_type* type = get_true_type((*f_iter)->get_type());
if (type->is_base_type()) {
t_base_type::t_base tbase = ((t_base_type*)type)->get_base();
switch (tbase) {
case t_base_type::TYPE_STRING:
case t_base_type::TYPE_DOUBLE:
case t_base_type::TYPE_UUID:
padding = " ";
break;
case t_base_type::TYPE_BOOL:
case t_base_type::TYPE_I8:
padding = " ";
break;
case t_base_type::TYPE_I16:
case t_base_type::TYPE_I32:
case t_base_type::TYPE_I64:
padding = " ";
break;
default: break;
}
} else if (type->is_enum() || type->is_set() || type->is_map()) {
padding = " ";
} else if (type->is_struct() || type->is_xception()) {
padding = " ";
} else if (type->is_list()) {
padding = " ";
}
out << padding << maybe_escape_identifier((*f_iter)->get_name()) << " = try "
<< type_name((*f_iter)->get_type(), false, false) << ".read(from: proto)" << '\n';
}
indent(out) << "case let (_, unknownType): try proto.skip(type: unknownType)" << '\n';
block_close(out);
out << '\n';
// Read field end marker
indent(out) << "try proto.readFieldEnd()" << '\n';
block_close(out);
out << '\n';
indent(out) << "try proto.readStructEnd()" << '\n';
if (struct_has_required_fields(tstruct)) {
// performs various checks (e.g. check that all required fields are set)
indent(out) << "// Required fields" << '\n';
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (field_is_optional(*f_iter)) {
continue;
}
indent(out) << "try proto.validateValue(" << maybe_escape_identifier((*f_iter)->get_name()) << ", "
<< "named: \"" << (*f_iter)->get_name() << "\")" << '\n';
}
}
out << '\n';
indent(out) << "return " << tstruct->get_name() << "(";
for (f_iter = fields.begin(); f_iter != fields.end();) {
out << (*f_iter)->get_name() << ": " << maybe_escape_identifier((*f_iter)->get_name());
if (++f_iter != fields.end()) {
out << ", ";
}
}
} else {
/** Legacy Swif2/Cocoa case */
string visibility = is_private ? "private" : "public";
indent(out) << visibility << " static func readValueFromProtocol(__proto: TProtocol) throws -> "
<< tstruct->get_name();
block_open(out);
out << '\n';
indent(out) << "try __proto.readStructBegin()" << '\n' << '\n';
const vector<t_field*>& fields = tstruct->get_members();
vector<t_field*>::const_iterator f_iter;
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
bool optional = field_is_optional(*f_iter);
indent(out) << "var " << maybe_escape_identifier((*f_iter)->get_name()) << " : "
<< type_name((*f_iter)->get_type(), optional, !optional) << '\n';
}
out << '\n';
// Loop over reading in fields
indent(out) << "fields: while true";
block_open(out);
out << '\n';
indent(out) << "let (_, fieldType, fieldID) = try __proto.readFieldBegin()" << '\n' << '\n';
indent(out) << "switch (fieldID, fieldType)";
block_open(out);
indent(out) << "case (_, .STOP):" << '\n';
indent_up();
indent(out) << "break fields" << '\n' << '\n';
indent_down();
// Generate deserialization code for known cases
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
indent(out) << "case (" << (*f_iter)->get_key() << ", " << type_to_enum((*f_iter)->get_type()) << "):" << '\n';
indent_up();
indent(out) << maybe_escape_identifier((*f_iter)->get_name()) << " = try __proto.readValue() as "
<< type_name((*f_iter)->get_type()) << '\n' << '\n';
indent_down();
}
indent(out) << "case let (_, unknownType):" << '\n';
indent_up();
indent(out) << "try __proto.skipType(unknownType)" << '\n';
indent_down();
block_close(out);
out << '\n';
// Read field end marker
indent(out) << "try __proto.readFieldEnd()" << '\n';
block_close(out);
out << '\n';
indent(out) << "try __proto.readStructEnd()" << '\n';
out << '\n';
if (struct_has_required_fields(tstruct)) {
// performs various checks (e.g. check that all required fields are set)
indent(out) << "// Required fields" << '\n';
for (f_iter = fields.begin(); f_iter != fields.end(); ++f_iter) {
if (field_is_optional(*f_iter)) {
continue;
}
indent(out) << "try __proto.validateValue(" << (*f_iter)->get_name() << ", "
<< "named: \"" << (*f_iter)->get_name() << "\")" << '\n';
}
}
out << '\n';
indent(out) << "return " << tstruct->get_name() << "(";
for (f_iter = fields.begin(); f_iter != fields.end();) {
out << (*f_iter)->get_name() << ": " << maybe_escape_identifier((*f_iter)->get_name());
if (++f_iter != fields.end()) {
out << ", ";
}
}
}
out << ")" << '\n';
block_close(out);
out << '\n';
}