private MethodDeclarationSyntax GenerateDeserializeInto(LayoutInfo layoutInfo, TypeSyntax dataType, ITypeSymbol dataTypeSymbol) { var statements = new List <StatementSyntax>(); var sortedMembers = layoutInfo.MemberInfos.OrderBy(a => a.LayoutAttribute.Offset); foreach (var member in sortedMembers) { var memberStatements = member.LayoutAttribute switch { PrimitiveValueAttribute prim => GeneratePrimitiveValueRead(member, prim, dataTypeSymbol), PrimitiveArrayAttribute arr => GeneratePrimitiveArrayRead(member, arr, dataTypeSymbol), InPlaceObjectAttribute obj => GenerateInPlaceObjectRead(member, obj, dataTypeSymbol), ReferenceValueAttribute refVal => GenerateReferenceValueRead(member, refVal, dataTypeSymbol), ReferenceArrayAttribute reference => GenerateReferenceArrayRead(member, reference, dataTypeSymbol), StringValueAttribute str => GenerateStringValueRead(member, str, dataTypeSymbol), Utf16StringValueAttribute str => GenerateStringValueRead(member, str, dataTypeSymbol), _ => Array.Empty <StatementSyntax>(), }; statements.AddRange(memberStatements); } statements.AddRange(GenerateInternedStringMembers(sortedMembers, dataTypeSymbol)); statements.Add(GenerateReturn()); var t = ParseTypeName(serializableType.ToDisplayString()); return(MethodDeclaration(t, SerializationClassAttribute.DeserializeIntoMethod) .AddParameterListParameters( Parameter(instanceParam).WithType(t), Parameter(dataParam).WithType(dataType), Parameter(startParam).WithType(PredefinedType(Token(SyntaxKind.IntKeyword))) .WithDefault(EqualsValueClause(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)))), Parameter(offsetParam).WithType(PredefinedType(Token(SyntaxKind.IntKeyword))) .WithDefault(EqualsValueClause(LiteralExpression(SyntaxKind.NumericLiteralExpression, Literal(0)))), Parameter(stringsParam).WithType(ParseTypeName(nameof(IInternedStringProvider))) .WithDefault(EqualsValueClause(LiteralExpression(SyntaxKind.NullLiteralExpression))) ) .AddModifiers(Token(SyntaxKind.PublicKeyword), Token(SyntaxKind.StaticKeyword)) .WithBody(Block(statements))); }
/// <summary> Write a PrimitiveArray XML Element from attributes in a member. </summary> public virtual void WritePrimitiveArray(System.Xml.XmlWriter writer, System.Reflection.MemberInfo member, PrimitiveArrayAttribute attribute, BaseAttribute parentAttribute, System.Type mappedClass) { writer.WriteStartElement( "primitive-array" ); // Attribute: <name> writer.WriteAttributeString("name", attribute.Name==null ? DefaultHelper.Get_PrimitiveArray_Name_DefaultValue(member) : GetAttributeValue(attribute.Name, mappedClass)); // Attribute: <access> if(attribute.Access != null) writer.WriteAttributeString("access", GetAttributeValue(attribute.Access, mappedClass)); // Attribute: <table> if(attribute.Table != null) writer.WriteAttributeString("table", GetAttributeValue(attribute.Table, mappedClass)); // Attribute: <schema> if(attribute.Schema != null) writer.WriteAttributeString("schema", GetAttributeValue(attribute.Schema, mappedClass)); // Attribute: <catalog> if(attribute.Catalog != null) writer.WriteAttributeString("catalog", GetAttributeValue(attribute.Catalog, mappedClass)); // Attribute: <subselect> if(attribute.Subselect != null) writer.WriteAttributeString("subselect", GetAttributeValue(attribute.Subselect, mappedClass)); // Attribute: <mutable> if( attribute.MutableSpecified ) writer.WriteAttributeString("mutable", attribute.Mutable ? "true" : "false"); // Attribute: <where> if(attribute.Where != null) writer.WriteAttributeString("where", GetAttributeValue(attribute.Where, mappedClass)); // Attribute: <batch-size> if(attribute.BatchSize != -1) writer.WriteAttributeString("batch-size", attribute.BatchSize.ToString()); // Attribute: <outer-join> if(attribute.OuterJoin != PrimitiveArrayOuterJoin.Unspecified) writer.WriteAttributeString("outer-join", GetXmlEnumValue(typeof(PrimitiveArrayOuterJoin), attribute.OuterJoin)); // Attribute: <fetch> if(attribute.Fetch != PrimitiveArrayFetch.Unspecified) writer.WriteAttributeString("fetch", GetXmlEnumValue(typeof(PrimitiveArrayFetch), attribute.Fetch)); // Attribute: <persister> if(attribute.Persister != null) writer.WriteAttributeString("persister", GetAttributeValue(attribute.Persister, mappedClass)); // Attribute: <collection-type> if(attribute.CollectionType != null) writer.WriteAttributeString("collection-type", GetAttributeValue(attribute.CollectionType, mappedClass)); // Attribute: <check> if(attribute.Check != null) writer.WriteAttributeString("check", GetAttributeValue(attribute.Check, mappedClass)); // Attribute: <optimistic-lock> if( attribute.OptimisticLockSpecified ) writer.WriteAttributeString("optimistic-lock", attribute.OptimisticLock ? "true" : "false"); // Attribute: <node> if(attribute.Node != null) writer.WriteAttributeString("node", GetAttributeValue(attribute.Node, mappedClass)); // Attribute: <embed-xml> if( attribute.EmbedXmlSpecified ) writer.WriteAttributeString("embed-xml", attribute.EmbedXml ? "true" : "false"); WriteUserDefinedContent(writer, member, null, attribute); System.Collections.ArrayList memberAttribs = GetSortedAttributes(member); int attribPos; // Find the position of the PrimitiveArrayAttribute (its <sub-element>s must be after it) for(attribPos=0; attribPos<memberAttribs.Count; attribPos++) if( memberAttribs[attribPos] is PrimitiveArrayAttribute && ((BaseAttribute)memberAttribs[attribPos]).Position == attribute.Position ) break; // found int i = attribPos + 1; // Element: <meta> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(MetaAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is MetaAttribute ) WriteMeta(writer, member, memberAttrib as MetaAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(MetaAttribute), attribute); // Element: <subselect> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(SubselectAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is SubselectAttribute ) WriteSubselect(writer, member, memberAttrib as SubselectAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(SubselectAttribute), attribute); // Element: <cache> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(CacheAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is CacheAttribute ) WriteCache(writer, member, memberAttrib as CacheAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(CacheAttribute), attribute); // Element: <synchronize> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(SynchronizeAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is SynchronizeAttribute ) WriteSynchronize(writer, member, memberAttrib as SynchronizeAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(SynchronizeAttribute), attribute); // Element: <comment> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(CommentAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is CommentAttribute ) WriteComment(writer, member, memberAttrib as CommentAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(CommentAttribute), attribute); // Element: <key> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(KeyAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is KeyAttribute ) WriteKey(writer, member, memberAttrib as KeyAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(KeyAttribute), attribute); // Element: <index> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(IndexAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is IndexAttribute ) WriteIndex(writer, member, memberAttrib as IndexAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(IndexAttribute), attribute); // Element: <list-index> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(ListIndexAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is ListIndexAttribute ) WriteListIndex(writer, member, memberAttrib as ListIndexAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(ListIndexAttribute), attribute); // Element: <element> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(ElementAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is ElementAttribute ) WriteElement(writer, member, memberAttrib as ElementAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(ElementAttribute), attribute); // Element: <loader> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(LoaderAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is LoaderAttribute ) WriteLoader(writer, member, memberAttrib as LoaderAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(LoaderAttribute), attribute); // Element: <sql-insert> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(SqlInsertAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is SqlInsertAttribute ) WriteSqlInsert(writer, member, memberAttrib as SqlInsertAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(SqlInsertAttribute), attribute); // Element: <sql-update> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(SqlUpdateAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is SqlUpdateAttribute ) WriteSqlUpdate(writer, member, memberAttrib as SqlUpdateAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(SqlUpdateAttribute), attribute); // Element: <sql-delete> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(SqlDeleteAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is SqlDeleteAttribute ) WriteSqlDelete(writer, member, memberAttrib as SqlDeleteAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(SqlDeleteAttribute), attribute); // Element: <sql-delete-all> for(; i<memberAttribs.Count; i++) { BaseAttribute memberAttrib = memberAttribs[i] as BaseAttribute; if( IsNextElement(memberAttrib, parentAttribute, attribute.GetType()) || IsNextElement(memberAttrib, attribute, typeof(SqlDeleteAllAttribute)) ) break; // next attributes are 'elements' of the same level OR for 'sub-elements' else { if( memberAttrib is PrimitiveArrayAttribute ) break; // Following attributes are for this PrimitiveArray if( memberAttrib is SqlDeleteAllAttribute ) WriteSqlDeleteAll(writer, member, memberAttrib as SqlDeleteAllAttribute, attribute, mappedClass); } } WriteUserDefinedContent(writer, member, typeof(SqlDeleteAllAttribute), attribute); writer.WriteEndElement(); }