private Expression ProcessFieldElement( Expression state, ParameterExpression requiredFields, IEnumerable <TransformSchemaPair> transforms) { var requiredIndex = 0; // start from the expression to handle unknown element (will be executed at the end of the if/else chain) Expression body = Expression.Block( Reader.Skip(), Expression.Assign(state, Expression.Constant(State.InsideStructElement))); // if there are transform/schema pairs for base structs, process their fields as well into the expression foreach (var pair in transforms) { var index = 0; var structDef = pair.Schema.StructDef; foreach (var field in pair.Transform.Fields) { var fieldDef = structDef.fields[index++]; Debug.Assert(field.Id == fieldDef.id); var parser = new SimpleXmlParser <R>(this, pair.Schema.GetFieldSchema(fieldDef)); // process field - and set the state to expect to see the field element's end var handleField = new List <Expression> { field.Value(parser, Expression.Constant(fieldDef.type.id)), Expression.Assign(state, Expression.Constant(State.AtFieldEndElement)) }; if (fieldDef.metadata.modifier == Modifier.Required) { handleField.Add(RequiredFields.Mark(requiredFields, requiredIndex++)); } body = Expression.IfThenElse( NodeNameEquals(fieldDef.metadata.name, structDef.metadata.GetXmlNamespace()), Expression.Block(handleField), body); } } return(body); }
Expression ProcessField(ParameterExpression requiredFields, IEnumerable <TransformSchemaPair> transforms) { // unknown fields are skipped (read past the unknown PropertyName then skip the value) Expression body = Expression.Block( Reader.Read(), SkipValue()); var requiredIndex = 0; foreach (var pair in transforms) { var currentSchema = pair.Schema; var currentTransform = pair.Transform; var structDef = currentSchema.StructDef; var index = 0; foreach (var field in currentTransform.Fields) { var fieldDef = structDef.fields[index++]; Debug.Assert(field.Id == fieldDef.id); var parser = new SimpleJsonParser <R>(this, currentSchema.GetFieldSchema(fieldDef)); // chain ifs on field name to handle the value on the right field handler var handleField = field.Value(parser, Expression.Constant(fieldDef.type.id)); if (fieldDef.metadata.modifier == Modifier.Required) { handleField = Expression.Block(RequiredFields.Mark(requiredFields, requiredIndex++), handleField); } string name; body = Expression.IfThenElse( PropertyNameEquals(fieldDef.metadata.attributes.TryGetValue( SimpleJsonWriter.NameAttribute, out name) ? name : fieldDef.metadata.name), Expression.Block(Read(), handleField), body); } } return(body); }