writeClassDecode method
void
writeClassDecode(
- CppOptions generatorOptions,
- Root root,
- Indent indent,
- Class classDefinition, {
- required String dartPackageName,
override
Writes a single class decode method to indent
.
Implementation
@override
void writeClassDecode(
CppOptions generatorOptions,
Root root,
Indent indent,
Class classDefinition, {
required String dartPackageName,
}) {
// Returns the expression to convert the given EncodableValue to a field
// value.
String getValueExpression(NamedType field, String encodable) {
if (field.type.isEnum) {
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, _shortBaseCppTypeForBuiltinDartType);
if (field.type.isClass) {
return _classReferenceFromEncodableValue(hostDatatype, encodable);
} else {
return 'std::get<${hostDatatype.datatype}>($encodable)';
}
}
}
_writeFunctionDefinition(indent, 'FromEncodableList',
scope: classDefinition.name,
returnType: classDefinition.name,
parameters: <String>['const EncodableList& list'], body: () {
const String instanceVariable = 'decoded';
final Iterable<_IndexedField> indexedFields = indexMap(
getFieldsInSerializationOrder(classDefinition),
(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('${classDefinition.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;');
});
}