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()))); }
public Expression Apply(ITransform transform) { Debug.Assert(schema.IsStruct); var body = new List <Expression> { transform.Begin }; if (schema.HasBase) { body.Add(transform.Base(new UntaggedParser <R>(this, schema.GetBaseSchema()))); } // Performs left outer join of schema fields with transform fields. // The result contains entry for each schema field. For fields not handled // by the transform default to Skip. body.AddRange( from fieldDef in schema.StructDef.fields join transfromField in transform.Fields on fieldDef.id equals transfromField.Id into fields from knownField in fields.DefaultIfEmpty() select Field(transform, fieldDef, knownField)); body.Add(transform.End); return(Expression.Block(body)); }
public Expression Apply(ITransform transform) { pairs.Add(new TransformSchemaPair(transform, schema)); if (schema.HasBase) { schema = schema.GetBaseSchema(); transform.Base(this); } return(Expression.Empty()); }