Expression Struct(IParser parser, RuntimeSchema schema, bool isBase) { var metadata = schema.HasValue ? Expression.Constant(schema.StructDef.metadata) : noMetadata; var baseSchema = schema.HasBase ? schema.GetBaseSchema() : RuntimeSchema.Empty; return(parser.Apply(new Transform( Begin: () => isBase ? writer.WriteBaseBegin(metadata) : writer.WriteStructBegin(metadata), End: () => isBase ? writer.WriteBaseEnd() : writer.WriteStructEnd(), Fields: schema.HasValue ? from field in schema.StructDef.fields select new Field( Id: field.id, Value: (fieldParser, fieldType) => Expression.Block( writer.WriteFieldBegin(fieldType, field.id, field.metadata), Value(fieldParser, fieldType, schema.GetFieldSchema(field)), writer.WriteFieldEnd()), Omitted: () => writer.WriteFieldOmitted(field.type.id, field.id, field.metadata)) : null, UnknownField: (fieldParser, fieldType, fieldId) => Expression.Block( writer.WriteFieldBegin(fieldType, fieldId, noMetadata), Value(fieldParser, fieldType), writer.WriteFieldEnd()), Base: baseParser => baseSchema.HasValue ? Struct(baseParser, baseSchema, isBase: true) : Expression.Empty(), UnknownEnd: () => writer.WriteBaseEnd()))); }
Expression Field(ITransform transform, FieldDef fieldDef, IField field) { var fieldId = Expression.Constant(fieldDef.id); var fieldType = Expression.Constant(fieldDef.type.id); var fieldParser = new UntaggedParser <R>(this, schema.GetFieldSchema(fieldDef)); return(Expression.IfThenElse(reader.ReadFieldOmitted(), field != null ? field.Omitted : Expression.Empty(), field != null ? field.Value(fieldParser, fieldType) : transform.UnknownField(fieldParser, fieldType, fieldId) ?? fieldParser.Skip(fieldType))); }