<?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:msxsl="urn:schemas-microsoft-com:xslt" exclude-result-prefixes="xsl msxsl" > <xsl:import href="common.xslt"/> <xsl:param name="help"/> <xsl:param name="xml"/> <xsl:param name="datacontract"/> <xsl:param name="binary"/> <xsl:param name="protoRpc"/> <xsl:param name="observable"/> <xsl:param name="preObservable"/> <xsl:param name="partialMethods"/> <xsl:param name="detectMissing"/> <xsl:param name="lightFramework"/> <xsl:param name="asynchronous"/> <xsl:param name="clientProxy"/> <xsl:param name="defaultNamespace"/> <xsl:param name="import"/> <xsl:key name="fieldNames" match="//FieldDescriptorProto" use="name"/> <xsl:output method="text" indent="no" omit-xml-declaration="yes"/> <xsl:variable name="optionXml" select="$xml='true'"/> <xsl:variable name="optionDataContract" select="$datacontract='true'"/> <xsl:variable name="optionBinary" select="$binary='true'"/> <xsl:variable name="optionProtoRpc" select="$protoRpc='true'"/> <xsl:variable name="optionObservable" select="$observable='true'"/> <xsl:variable name="optionPreObservable" select="$preObservable='true'"/> <xsl:variable name="optionPartialMethods" select="$partialMethods='true'"/> <xsl:variable name="optionDetectMissing" select="$detectMissing='true'"/> <xsl:variable name="optionFullFramework" select="not($lightFramework='true')"/> <xsl:variable name="optionAsynchronous" select="$asynchronous='true'"/> <xsl:variable name="optionClientProxy" select="$clientProxy='true'"/> <xsl:template match="/"> <xsl:text disable-output-escaping="yes">//------------------------------------------------------------------------------ // <auto-generated> // This code was generated by a tool. // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using CommonLang.IO; using System.Collections.Generic; </xsl:text><!-- --><xsl:apply-templates select="*"/><!-- --></xsl:template> <xsl:template name="WriteUsings"> <xsl:param name="ns"/> <xsl:if test="$ns != ''"><xsl:choose> <xsl:when test="contains($ns,';')"> using <xsl:value-of select="substring-before($ns,';')"/>;<!-- --><xsl:call-template name="WriteUsings"> <xsl:with-param name="ns" select="substring-after($ns,';')"/> </xsl:call-template> </xsl:when> <xsl:otherwise> using <xsl:value-of select="$ns"/>; </xsl:otherwise> </xsl:choose></xsl:if></xsl:template> <xsl:template match="FileDescriptorSet"> <xsl:if test="$help='true'"> <xsl:message terminate="yes"> CSharp template for protobuf-net. Options: General: "help" - this page Additional serializer support: "xml" - enable explicit xml support (XmlSerializer) "datacontract" - enable data-contract support (DataContractSerializer; requires .NET 3.0) "binary" - enable binary support (BinaryFormatter; not supported on Silverlight) Other: "protoRpc" - enable proto-rpc client "observable" - change notification (observer pattern) support "preObservable" - pre-change notification (observer pattern) support (requires .NET 3.5) "partialMethods" - provide partial methods for changes (requires C# 3.0) "detectMissing" - provide *Specified properties to indicate whether fields are present "lightFramework" - omit additional attributes not included in CF/Silverlight "asynchronous" - emit asynchronous methods for use with WCF "clientProxy" - emit asynchronous client proxy class "import" - additional namespaces to import (semicolon delimited) "fixCase" - change type/member names (types/properties become PascalCase; fields become camelCase) </xsl:message> </xsl:if> <xsl:if test="$optionXml and $optionDataContract"> <xsl:message terminate="yes"> Invalid options: xml and data-contract serialization are mutually exclusive. </xsl:message> </xsl:if> <xsl:if test="$optionXml"> // Option: xml serialization ([XmlType]/[XmlElement]) enabled </xsl:if><xsl:if test="$optionDataContract"> // Option: data-contract serialization ([DataContract]/[DataMember]) enabled </xsl:if><xsl:if test="$optionBinary"> // Option: binary serialization (ISerializable) enabled </xsl:if><xsl:if test="$optionObservable"> // Option: observable (OnPropertyChanged) enabled </xsl:if><xsl:if test="$optionPreObservable"> // Option: pre-observable (OnPropertyChanging) enabled </xsl:if><xsl:if test="$partialMethods"> // Option: partial methods (On*Changing/On*Changed) enabled </xsl:if><xsl:if test="$optionDetectMissing"> // Option: missing-value detection (*Specified/ShouldSerialize*/Reset*) enabled </xsl:if><xsl:if test="not($optionFullFramework)"> // Option: light framework (CF/Silverlight) enabled </xsl:if><xsl:if test="$optionProtoRpc"> // Option: proto-rpc enabled </xsl:if> <xsl:call-template name="WriteUsings"> <xsl:with-param name="ns" select="$import"/> </xsl:call-template> <xsl:apply-templates select="file/FileDescriptorProto"/> </xsl:template> <xsl:template match="FileDescriptorProto"> <xsl:apply-templates select="comments/string[.!='']"/> // Generated from: <xsl:value-of select="name"/> <xsl:apply-templates select="dependency/string[.!='']"/> <xsl:variable name="namespace"><xsl:call-template name="PickNamespace"> <xsl:with-param name="defaultNamespace" select="$defaultNamespace"/> </xsl:call-template> </xsl:variable> <xsl:if test="string($namespace) != ''"> namespace <xsl:value-of select="translate($namespace,':-/\','__..')"/> { </xsl:if> <xsl:apply-templates select="message_type | enum_type | service"/> <xsl:if test="string($namespace) != ''"> } </xsl:if> </xsl:template> <xsl:template match="FileDescriptorProto/dependency/string"> // Note: requires additional types generated from: <xsl:value-of select="."/></xsl:template> <xsl:template name="camel"> <xsl:param name="value" select="name"/> <xsl:param name="delimiter" select="'_'"/> <xsl:choose> <xsl:when test="$optionFixCase"><xsl:call-template name="toCamelCase"> <xsl:with-param name="value" select="$value"/> <xsl:with-param name="delimiter" select="$delimiter"/> </xsl:call-template></xsl:when> <xsl:otherwise><xsl:value-of select="$value"/></xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="DescriptorProto"> //--------------------------------------------------------------------------------------- <xsl:apply-templates select="comments/string[.!='']"/> public class <xsl:call-template name="pascal"/> : CommonLang.Protocol.NetMessage { public <xsl:call-template name="pascal"/>() {} <xsl:apply-templates select="*"/> public override void ReadExternal(IInputStream input) { <xsl:apply-templates select="field" mode="stream_read"/> } public override void WriteExternal(IOutputStream output) { <xsl:apply-templates select="field" mode="stream_write"/> } } </xsl:template> <xsl:template match="DescriptorProto/name | DescriptorProto/extension_range | DescriptorProto/extension | DescriptorProto/comments"/> <xsl:template match=" FileDescriptorProto/message_type | FileDescriptorProto/enum_type | FileDescriptorProto/service | DescriptorProto/enum_type | DescriptorProto/message_type | DescriptorProto/nested_type | EnumDescriptorProto/value | ServiceDescriptorProto/method"> <xsl:apply-templates select="*"/> </xsl:template> <xsl:template match="DescriptorProto/field"> <xsl:apply-templates select="*"/> <xsl:variable name="extName" select="concat('.',(ancestor::FileDescriptorProto/package)[1],'.',../name)"/> <xsl:apply-templates select="//FieldDescriptorProto[extendee=$extName]"/> </xsl:template> <xsl:template match="DescriptorProto/field" mode="stream_read"> <xsl:apply-templates select="*" mode="stream_read"/> </xsl:template> <xsl:template match="DescriptorProto/field" mode="stream_write"> <xsl:apply-templates select="*" mode="stream_write"/> </xsl:template> <xsl:template match="EnumDescriptorProto"> //--------------------------------------------------------------------------------------- <xsl:apply-templates select="comments/string[.!='']"/> public enum <xsl:call-template name="pascal"/> { <xsl:apply-templates select="value"/> } </xsl:template> <xsl:template match="EnumValueDescriptorProto"> <xsl:variable name="value"><xsl:choose> <xsl:when test="number"><xsl:value-of select="number"/></xsl:when> <xsl:otherwise>0</xsl:otherwise> </xsl:choose></xsl:variable><xsl:apply-templates select="comments/string[.!='']"/> <!-- --><xsl:text disable-output-escaping="yes"> </xsl:text><xsl:call-template name="pascal"/><xsl:text xml:space="preserve"> = </xsl:text><xsl:value-of select="$value"/><xsl:if test="position()!=last()">, </xsl:if> </xsl:template> <xsl:template match="FieldDescriptorProto" mode="field"> <xsl:variable name="field"><xsl:choose> <xsl:when test="$optionFixCase"><xsl:call-template name="toCamelCase"> <xsl:with-param name="value" select="name"/> </xsl:call-template></xsl:when> <xsl:otherwise><xsl:value-of select="name"/></xsl:otherwise> </xsl:choose></xsl:variable> <xsl:call-template name="escapeKeyword"> <xsl:with-param name="value"><xsl:choose> <xsl:when test="not(key('fieldNames',concat('_',$field)))"><xsl:value-of select="concat('_',$field)"/></xsl:when> <xsl:when test="not(key('fieldNames',concat($field,'Field')))"><xsl:value-of select="concat($field,'Field')"/></xsl:when> <xsl:otherwise><xsl:value-of select="concat('_',generate-id())"/></xsl:otherwise> </xsl:choose></xsl:with-param> </xsl:call-template> </xsl:template> <xsl:template name="escapeKeyword"> <xsl:param name="value"/> <xsl:if test="contains($keywords,concat('|',$value,'|'))">@</xsl:if><xsl:value-of select="$value"/> </xsl:template> <xsl:variable name="keywords">|abstract|as|base|bool|break|byte|case|catch|char|checked|class|const|continue|decimal|default|delegate|do|double|else|enum|event|explicit|extern|false|finally|fixed|float|for|foreach|goto|if|implicit|in|int|interface|internal|is|lock|long|namespace|new|null|object|operator|out|override|params|private|protected|public|readonly|ref|return|sbyte|sealed|short|sizeof|stackalloc|static|string|struct|switch|this|throw|true|try|typeof|uint|ulong|unchecked|unsafe|ushort|using|virtual|void|volatile|while|</xsl:variable> <xsl:template match="FieldDescriptorProto" mode="format"> <xsl:choose> <xsl:when test="type='TYPE_DOUBLE' or type='TYPE_FLOAT' or type='TYPE_FIXED32' or type='TYPE_FIXED64' or type='TYPE_SFIXED32' or type='TYPE_SFIXED64'">FixedSize</xsl:when> <xsl:when test="type='TYPE_GROUP'">Group</xsl:when> <xsl:when test="not(type) or type='TYPE_INT32' or type='TYPE_INT64' or type='TYPE_UINT32' or type='TYPE_UINT64' or type='TYPE_ENUM'">TwosComplement</xsl:when> <xsl:when test="type='TYPE_SINT32' or type='TYPE_SINT64'">ZigZag</xsl:when> <xsl:otherwise>Default</xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="FieldDescriptorProto" mode="primitiveType"> <xsl:choose> <xsl:when test="not(type)">struct</xsl:when> <xsl:when test="type='TYPE_DOUBLE'">struct</xsl:when> <xsl:when test="type='TYPE_FLOAT'">struct</xsl:when> <xsl:when test="type='TYPE_INT64'">struct</xsl:when> <xsl:when test="type='TYPE_UINT64'">struct</xsl:when> <xsl:when test="type='TYPE_INT32'">struct</xsl:when> <xsl:when test="type='TYPE_FIXED64'">struct</xsl:when> <xsl:when test="type='TYPE_FIXED32'">struct</xsl:when> <xsl:when test="type='TYPE_BOOL'">struct</xsl:when> <xsl:when test="type='TYPE_STRING'">class</xsl:when> <xsl:when test="type='TYPE_BYTES'">class</xsl:when> <xsl:when test="type='TYPE_UINT32'">struct</xsl:when> <xsl:when test="type='TYPE_SFIXED32'">struct</xsl:when> <xsl:when test="type='TYPE_SFIXED64'">struct</xsl:when> <xsl:when test="type='TYPE_SINT32'">struct</xsl:when> <xsl:when test="type='TYPE_SINT64'">struct</xsl:when> <xsl:when test="type='TYPE_ENUM'">struct</xsl:when> <xsl:when test="type='TYPE_GROUP' or type='TYPE_MESSAGE'">none</xsl:when> <xsl:otherwise> <xsl:message terminate="yes"> Field type not implemented: <xsl:value-of select="type"/> (<xsl:value-of select="../../name"/>.<xsl:value-of select="name"/>) </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="FieldDescriptorProto" mode="type"> <xsl:choose> <xsl:when test="not(type)">double</xsl:when> <xsl:when test="type='TYPE_DOUBLE'">double</xsl:when> <xsl:when test="type='TYPE_FLOAT'">float</xsl:when> <xsl:when test="type='TYPE_INT64'">long</xsl:when> <xsl:when test="type='TYPE_UINT64'">ulong</xsl:when> <xsl:when test="type='TYPE_INT32'">int</xsl:when> <xsl:when test="type='TYPE_FIXED64'">ulong</xsl:when> <xsl:when test="type='TYPE_FIXED32'">uint</xsl:when> <xsl:when test="type='TYPE_BOOL'">bool</xsl:when> <xsl:when test="type='TYPE_STRING'">string</xsl:when> <xsl:when test="type='TYPE_BYTES'">byte[]</xsl:when> <xsl:when test="type='TYPE_UINT32'">uint</xsl:when> <xsl:when test="type='TYPE_SFIXED32'">int</xsl:when> <xsl:when test="type='TYPE_SFIXED64'">long</xsl:when> <xsl:when test="type='TYPE_SINT32'">int</xsl:when> <xsl:when test="type='TYPE_SINT64'">long</xsl:when> <xsl:when test="type='TYPE_GROUP' or type='TYPE_MESSAGE' or type='TYPE_ENUM'"><xsl:call-template name="pascal"> <xsl:with-param name="value" select="substring-after(type_name,'.')"/> </xsl:call-template></xsl:when> <xsl:otherwise> <xsl:message terminate="yes"> Field type not implemented: <xsl:value-of select="type"/> (<xsl:value-of select="../../name"/>.<xsl:value-of select="name"/>) </xsl:message> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="FieldDescriptorProto[default_value]" mode="defaultValue"> <xsl:choose> <xsl:when test="type='TYPE_STRING'">@"<xsl:value-of select="default_value"/>"</xsl:when> <xsl:when test="type='TYPE_ENUM'"><xsl:apply-templates select="." mode="type"/>.<xsl:call-template name="pascal"> <xsl:with-param name="value" select="default_value"/> </xsl:call-template></xsl:when> <xsl:when test="type='TYPE_BYTES'"> /* <xsl:value-of select="default_value"/> */ null </xsl:when> <xsl:otherwise>(<xsl:apply-templates select="." mode="type"/>)<xsl:value-of select="default_value"/></xsl:otherwise> </xsl:choose> </xsl:template> <!-- We need to find the first enum value given .foo.bar.SomeEnum - but the enum itself only knows about SomeEnum; we need to look at all parent DescriptorProto nodes, and the FileDescriptorProto for the namespace. This does an annoying up/down recursion... a bit expensive, but *generally* OK. Could perhaps index the last part of the enum name to reduce overhead? --> <xsl:template name="GetFirstEnumValue"> <xsl:variable name="hunt" select="type_name"/> <xsl:for-each select="//EnumDescriptorProto"> <xsl:variable name="fullName"> <xsl:for-each select="ancestor::FileDescriptorProto[package!='']">.<xsl:value-of select="package"/></xsl:for-each> <xsl:for-each select="ancestor::DescriptorProto">.<xsl:value-of select="name"/></xsl:for-each> <xsl:value-of select="'.'"/> <xsl:call-template name="pascal"/> </xsl:variable> <xsl:if test="$fullName=$hunt"><xsl:value-of select="(value/EnumValueDescriptorProto)[1]/name"/></xsl:if> </xsl:for-each> </xsl:template> <xsl:template match="FieldDescriptorProto[not(default_value)]" mode="defaultValue"> <xsl:choose> <xsl:when test="type='TYPE_STRING'">""</xsl:when> <xsl:when test="type='TYPE_MESSAGE'">null</xsl:when> <xsl:when test="type='TYPE_BYTES'">null</xsl:when> <xsl:when test="type='TYPE_ENUM'"><xsl:apply-templates select="." mode="type"/>.<xsl:call-template name="GetFirstEnumValue"/></xsl:when> <xsl:otherwise>default(<xsl:apply-templates select="." mode="type"/>)</xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="FieldDescriptorProto" mode="checkDeprecated"><!-- --><xsl:if test="options/deprecated='true'">global::System.Obsolete, </xsl:if><!-- --></xsl:template> <xsl:template match="FieldDescriptorProto[label='LABEL_OPTIONAL' or not(label)]"> <xsl:variable name="propType"><xsl:apply-templates select="." mode="type"/></xsl:variable> <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable> <xsl:variable name="primitiveType"><xsl:apply-templates select="." mode="primitiveType"/></xsl:variable> <xsl:variable name="defaultValue"><xsl:apply-templates select="." mode="defaultValue"/></xsl:variable> <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable> <xsl:variable name="specified" select="$optionDetectMissing and ($primitiveType='struct' or $primitiveType='class')"/> <xsl:variable name="fieldType"><xsl:value-of select="$propType"/><xsl:if test="$specified and $primitiveType='struct'">?</xsl:if></xsl:variable> <xsl:apply-templates select="comments/string[.!='']"/> public <xsl:value-of select="concat($fieldType,' ',name)"/><xsl:if test="not($specified)"> = <xsl:value-of select="$defaultValue"/></xsl:if>; </xsl:template> <xsl:template match="FieldDescriptorProto[label='LABEL_REQUIRED']"> <xsl:variable name="type"><xsl:apply-templates select="." mode="type"/></xsl:variable> <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable> <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable> <xsl:apply-templates select="comments/string[.!='']"/> public <xsl:value-of select="concat($type, ' ', name)"/>; </xsl:template> <xsl:template name="stripKeyword"> <xsl:param name="value"/> <xsl:choose> <xsl:when test="starts-with($value,'@')"><xsl:value-of select="substring-after($value,'@')"/></xsl:when> <xsl:otherwise><xsl:value-of select="$value"/></xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="FieldDescriptorProto[label='LABEL_REPEATED']"> <xsl:variable name="type"><xsl:apply-templates select="." mode="type"/></xsl:variable> <xsl:variable name="format"><xsl:apply-templates select="." mode="format"/></xsl:variable> <xsl:variable name="field"><xsl:apply-templates select="." mode="field"/></xsl:variable> <xsl:apply-templates select="comments/string[.!='']"/> public List<<xsl:value-of select="$type" />> <xsl:value-of select="name"/> = new List<<xsl:value-of select="$type"/>>(); </xsl:template> <xsl:template match="FieldDescriptorProto" mode="stream_read"><!-- -->    this.<xsl:value-of select="name"/> = <xsl:if test="label='LABEL_REPEATED'">input.GetList<<xsl:apply-templates select="." mode="type"/>>(</xsl:if> <xsl:if test="not(type)">input.GetF64</xsl:if> <xsl:if test="type='TYPE_DOUBLE'">input.GetF64</xsl:if> <xsl:if test="type='TYPE_FLOAT'">input.GetF32</xsl:if> <xsl:if test="type='TYPE_INT64'">input.GetS64</xsl:if> <xsl:if test="type='TYPE_UINT64'">input.GetU64</xsl:if> <xsl:if test="type='TYPE_INT32'">input.GetS32</xsl:if> <xsl:if test="type='TYPE_FIXED64'">input.GetU64</xsl:if> <xsl:if test="type='TYPE_FIXED32'">input.GetU32</xsl:if> <xsl:if test="type='TYPE_BOOL'">input.GetBool</xsl:if> <xsl:if test="type='TYPE_STRING'">input.GetUTF</xsl:if> <xsl:if test="type='TYPE_BYTES'">input.GetBytes</xsl:if> <xsl:if test="type='TYPE_UINT32'">input.GetU32</xsl:if> <xsl:if test="type='TYPE_SFIXED32'">input.GetS32</xsl:if> <xsl:if test="type='TYPE_SFIXED64'">input.GetS64</xsl:if> <xsl:if test="type='TYPE_SINT32'">input.GetS32</xsl:if> <xsl:if test="type='TYPE_SINT64'">input.GetS64</xsl:if> <xsl:if test="type='TYPE_MESSAGE'">input.GetExt<<xsl:apply-templates select="." mode="type"/>></xsl:if> <xsl:if test="type='TYPE_ENUM'">input.GetEnum8<<xsl:apply-templates select="." mode="type"/>></xsl:if> <xsl:choose><xsl:when test="label='LABEL_REPEATED'">)</xsl:when><xsl:otherwise>()</xsl:otherwise></xsl:choose>; </xsl:template> <xsl:template match="FieldDescriptorProto" mode="stream_write"><!-- -->    <xsl:if test="label='LABEL_REPEATED'">output.PutList<<xsl:apply-templates select="." mode="type"/>>(this.<xsl:value-of select="name"/>, </xsl:if> <xsl:if test="not(type)">output.PutF64</xsl:if> <xsl:if test="type='TYPE_DOUBLE'">output.PutF64</xsl:if> <xsl:if test="type='TYPE_FLOAT'">output.PutF32</xsl:if> <xsl:if test="type='TYPE_INT64'">output.PutS64</xsl:if> <xsl:if test="type='TYPE_UINT64'">output.PutU64</xsl:if> <xsl:if test="type='TYPE_INT32'">output.PutS32</xsl:if> <xsl:if test="type='TYPE_FIXED64'">output.PutU64</xsl:if> <xsl:if test="type='TYPE_FIXED32'">output.PutU32</xsl:if> <xsl:if test="type='TYPE_BOOL'">output.PutBool</xsl:if> <xsl:if test="type='TYPE_STRING'">output.PutUTF</xsl:if> <xsl:if test="type='TYPE_BYTES'">output.PutBytes</xsl:if> <xsl:if test="type='TYPE_UINT32'">output.PutU32</xsl:if> <xsl:if test="type='TYPE_SFIXED32'">output.PutS32</xsl:if> <xsl:if test="type='TYPE_SFIXED64'">output.PutS64</xsl:if> <xsl:if test="type='TYPE_SINT32'">output.PutS32</xsl:if> <xsl:if test="type='TYPE_SINT64'">output.PutS64</xsl:if> <xsl:if test="type='TYPE_MESSAGE'">output.PutExt</xsl:if> <xsl:if test="type='TYPE_ENUM'">output.PutEnum8<<xsl:apply-templates select="." mode="type"/>></xsl:if> <xsl:choose><xsl:when test="label='LABEL_REPEATED'">)</xsl:when><xsl:otherwise>(this.<xsl:value-of select="name"/>)</xsl:otherwise></xsl:choose>; </xsl:template> <xsl:template match="FileDescriptorProto/comments/string"> // <xsl:value-of select="."/> </xsl:template> <xsl:template match="DescriptorProto/comments/string"> /// <summary> /// <xsl:value-of select="."/> /// </summary></xsl:template> <xsl:template match="EnumDescriptorProto/comments/string"> /// <summary> /// <xsl:value-of select="."/> /// </summary></xsl:template> <xsl:template match="FieldDescriptorProto/comments/string"> /// <summary> /// <xsl:value-of select="."/> /// </summary></xsl:template> <xsl:template match="EnumValueDescriptorProto/comments/string"> /// <summary> /// <xsl:value-of select="."/> /// </summary></xsl:template> </xsl:stylesheet>