writeClassDecode method
void
writeClassDecode(
- CppOptions generatorOptions,
- Root root,
- Indent indent,
- Class klass,
- Set<
String> customClassNames, - Set<
String> customEnumNames, { - required String dartPackageName,
override
Writes a single class decode method to indent
.
Implementation
@override
void writeClassDecode(
CppOptions generatorOptions,
Root root,
Indent indent,
Class klass,
Set<String> customClassNames,
Set<String> customEnumNames, {
required String dartPackageName,
}) {
// Returns the expression to convert the given EncodableValue to a field
// value.
String getValueExpression(NamedType field, String encodable) {
if (customEnumNames.contains(field.type.baseName)) {
return '(${field.type.baseName})(std::get<int32_t>($encodable))';
} else if (field.type.baseName == 'int') {
return '$encodable.LongValue()';
} else if (field.type.baseName == 'Object') {
return encodable;
} else {
final HostDatatype hostDatatype = getFieldHostDatatype(field,
root.classes, root.enums, _shortBaseCppTypeForBuiltinDartType);
if (!hostDatatype.isBuiltin &&
root.classes
.map((Class x) => x.name)
.contains(field.type.baseName)) {
return '${hostDatatype.datatype}::FromEncodableList(std::get<EncodableList>($encodable))';
} else {
return 'std::get<${hostDatatype.datatype}>($encodable)';
}
}
}
_writeFunctionDefinition(indent, 'FromEncodableList',
scope: klass.name,
returnType: klass.name,
parameters: <String>['const EncodableList& list'], body: () {
const String instanceVariable = 'decoded';
final Iterable<_IndexedField> indexedFields = indexMap(
getFieldsInSerializationOrder(klass),
(int index, NamedType field) => _IndexedField(index, field));
final Iterable<_IndexedField> nullableFields = indexedFields
.where((_IndexedField field) => field.field.type.isNullable);
final Iterable<_IndexedField> nonNullableFields = indexedFields
.where((_IndexedField field) => !field.field.type.isNullable);
// Non-nullable fields must be set via the constructor.
String constructorArgs = nonNullableFields
.map((_IndexedField param) =>
getValueExpression(param.field, 'list[${param.index}]'))
.join(',\n\t');
if (constructorArgs.isNotEmpty) {
constructorArgs = '(\n\t$constructorArgs)';
}
indent.format('${klass.name} $instanceVariable$constructorArgs;');
// Add the nullable fields via setters, since converting the encodable
// values to the pointer types that the convenience constructor uses for
// nullable fields is non-trivial.
for (final _IndexedField entry in nullableFields) {
final NamedType field = entry.field;
final String setterName = _makeSetterName(field);
final String encodableFieldName =
'${_encodablePrefix}_${_makeVariableName(field)}';
indent.writeln('auto& $encodableFieldName = list[${entry.index}];');
final String valueExpression =
getValueExpression(field, encodableFieldName);
indent.writeScoped('if (!$encodableFieldName.IsNull()) {', '}', () {
indent.writeln('$instanceVariable.$setterName($valueExpression);');
});
}
// This returns by value, relying on copy elision, since it makes the
// usage more convenient during deserialization than it would be with
// explicit transfer via unique_ptr.
indent.writeln('return $instanceVariable;');
});
}