Created
October 9, 2012 13:39
-
-
Save LeeCampbell/3858868 to your computer and use it in GitHub Desktop.
Protobuf-Net xslt file to produce Nullable Properties
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<!-- | |
In conjunction with the patch for issue 72 | |
https://code.google.com/p/protobuf-net/issues/detail?id=72 | |
This file can make the current implementation of the Protobuf-net tools useful. Without these however protobuf-net is full of surprises like: | |
* Requiring you to specify if it should detect missing values (why is this not always on?) | |
* Not being able to identify between not specified (null in every other computer system) and the default value | |
* Not being able to compile if an Enum is optional but does not specify a default value?! | |
* Happily serializing invalid messages i.e. where required values are missing | |
--> | |
<?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> | |
//------------------------------------------------------------------------------ | |
</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="$detectMissing"> | |
// 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"> | |
// 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:if test="$optionFullFramework">global::System.Serializable, </xsl:if>global::ProtoBuf.ProtoContract(Name=@"<xsl:value-of select="name"/>")] | |
<xsl:if test="$optionDataContract">[global::System.Runtime.Serialization.DataContract(Name=@"<xsl:value-of select="name"/>")] | |
</xsl:if><xsl:if test="$optionXml">[global::System.Xml.Serialization.XmlType(TypeName=@"<xsl:value-of select="name"/>")] | |
</xsl:if><!-- | |
-->public partial class <xsl:call-template name="pascal"/> : global::ProtoBuf.IExtensible<!-- | |
--><xsl:if test="$optionBinary">, global::System.Runtime.Serialization.ISerializable</xsl:if><!-- | |
--><xsl:if test="$optionObservable">, global::System.ComponentModel.INotifyPropertyChanged</xsl:if><!-- | |
--><xsl:if test="$optionPreObservable">, global::System.ComponentModel.INotifyPropertyChanging</xsl:if> | |
{ | |
public <xsl:call-template name="pascal"/>() {} | |
<xsl:apply-templates select="*"/><xsl:if test="$optionBinary"> | |
protected <xsl:call-template name="pascal"/>(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) | |
: this() { global::ProtoBuf.Serializer.Merge(info, this); } | |
void global::System.Runtime.Serialization.ISerializable.GetObjectData(global::System.Runtime.Serialization.SerializationInfo info, global::System.Runtime.Serialization.StreamingContext context) | |
{ global::ProtoBuf.Serializer.Serialize(info, this); } | |
</xsl:if><xsl:if test="$optionObservable"> | |
public event global::System.ComponentModel.PropertyChangedEventHandler PropertyChanged; | |
protected virtual void OnPropertyChanged(string propertyName) | |
{ if(PropertyChanged != null) PropertyChanged(this, new global::System.ComponentModel.PropertyChangedEventArgs(propertyName)); } | |
</xsl:if><xsl:if test="$optionPreObservable"> | |
public event global::System.ComponentModel.PropertyChangingEventHandler PropertyChanging; | |
protected virtual void OnPropertyChanging(string propertyName) | |
{ if(PropertyChanging != null) PropertyChanging(this, new global::System.ComponentModel.PropertyChangingEventArgs(propertyName)); } | |
</xsl:if> | |
private global::ProtoBuf.IExtension extensionObject; | |
global::ProtoBuf.IExtension global::ProtoBuf.IExtensible.GetExtensionObject(bool createIfMissing) | |
{ return global::ProtoBuf.Extensible.GetExtensionObject(ref extensionObject, createIfMissing); } | |
} | |
</xsl:template> | |
<xsl:template match="DescriptorProto/name | DescriptorProto/extension_range | DescriptorProto/extension"/> | |
<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="EnumDescriptorProto"> | |
[global::ProtoBuf.ProtoContract(Name=@"<xsl:value-of select="name"/>")] | |
<xsl:if test="$optionDataContract">[global::System.Runtime.Serialization.DataContract(Name=@"<xsl:value-of select="name"/>")] | |
</xsl:if> | |
<xsl:if test="$optionXml">[global::System.Xml.Serialization.XmlType(TypeName=@"<xsl:value-of select="name"/>")] | |
</xsl:if><!-- | |
-->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> | |
[global::ProtoBuf.ProtoEnum(Name=@"<xsl:value-of select="name"/>", Value=<xsl:value-of select="$value"/>)]<!-- | |
--><xsl:if test="$optionDataContract"> | |
[global::System.Runtime.Serialization.EnumMember(Value=@"<xsl:value-of select="name"/>")]</xsl:if><!-- | |
--><xsl:if test="$optionXml"> | |
[global::System.Xml.Serialization.XmlEnum(@"<xsl:value-of select="name"/>")]</xsl:if><!-- | |
--><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">.<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="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="format"><xsl:apply-templates select="." mode="format"/></xsl:variable> | |
<xsl:variable name="underlyingtype"><xsl:apply-templates select="." mode="type"/></xsl:variable> | |
<xsl:variable name="propType"><xsl:value-of select="$underlyingtype"/><xsl:if test="$specified and $primitiveType='struct'">?</xsl:if></xsl:variable> | |
<xsl:variable name="fieldType"><xsl:value-of select="$underlyingtype"/><xsl:if test="$specified and $primitiveType='struct'">?</xsl:if></xsl:variable> | |
private <xsl:value-of select="concat($fieldType,' ',$field)"/><xsl:if test="not($specified)"> = <xsl:value-of select="$defaultValue"/></xsl:if>; | |
[<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, IsRequired = false, Name=@"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/>)]<!-- | |
--><xsl:if test="not($specified)"> | |
[global::System.ComponentModel.DefaultValue(<xsl:value-of select="$defaultValue"/>)]</xsl:if><!-- | |
--><xsl:if test="$optionXml"> | |
[global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)] | |
</xsl:if><xsl:if test="$optionDataContract"> | |
[global::System.Runtime.Serialization.DataMember(Name=@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = false)] | |
</xsl:if><xsl:call-template name="WriteGetSet"> | |
<xsl:with-param name="fieldType" select="$fieldType"/> | |
<xsl:with-param name="propType" select="$propType"/> | |
<xsl:with-param name="name"><xsl:call-template name="pascal"/></xsl:with-param> | |
<xsl:with-param name="field" select="$field"/> | |
<xsl:with-param name="defaultValue" select="$defaultValue"/> | |
<xsl:with-param name="specified" select="$specified"/> | |
</xsl:call-template> | |
</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> | |
private <xsl:value-of select="concat($type, ' ', $field)"/>; | |
[<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, IsRequired = true, Name=@"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/>)]<!-- | |
--><xsl:if test="$optionXml"> | |
[global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)] | |
</xsl:if><xsl:if test="$optionDataContract"> | |
[global::System.Runtime.Serialization.DataMember(Name=@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = true)] | |
</xsl:if><xsl:call-template name="WriteGetSet"> | |
<xsl:with-param name="fieldType" select="$type"/> | |
<xsl:with-param name="propType" select="$type"/> | |
<xsl:with-param name="name"><xsl:call-template name="pascal"/></xsl:with-param> | |
<xsl:with-param name="field" select="$field"/> | |
</xsl:call-template> | |
</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 name="WriteGetSet"> | |
<xsl:param name="fieldType"/> | |
<xsl:param name="propType"/> | |
<xsl:param name="name"/> | |
<xsl:param name="field"/> | |
<xsl:param name="specified" select="false()"/> | |
<xsl:param name="defaultValue"/> | |
<xsl:variable name="nameNoKeyword"> | |
<xsl:call-template name="stripKeyword"> | |
<xsl:with-param name="value" select="$name"/> | |
</xsl:call-template></xsl:variable> | |
public <xsl:value-of select="concat($propType,' ',$name)"/> | |
{ | |
get { return <xsl:value-of select="$field"/>; } | |
set { <xsl:if test="$optionPartialMethods">On<xsl:value-of select="$nameNoKeyword"/>Changing(value); </xsl:if><xsl:if test="$optionPreObservable">OnPropertyChanging(@"<xsl:value-of select="$nameNoKeyword"/>"); </xsl:if><xsl:value-of select="$field"/> = value; <xsl:if test="$optionObservable">OnPropertyChanged(@"<xsl:value-of select="$nameNoKeyword"/>"); </xsl:if><xsl:if test="$optionPartialMethods">On<xsl:value-of select="$nameNoKeyword"/>Changed();</xsl:if>} | |
}<xsl:if test="$optionPartialMethods"> | |
partial void On<xsl:value-of select="$nameNoKeyword"/>Changing(<xsl:value-of select="$propType"/> value); | |
partial void On<xsl:value-of select="$nameNoKeyword"/>Changed();</xsl:if> | |
</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> | |
private <xsl:if test="not($optionXml)">readonly</xsl:if> global::System.Collections.Generic.List<<xsl:value-of select="$type" />> <xsl:value-of select="$field"/> = new global::System.Collections.Generic.List<<xsl:value-of select="$type"/>>(); | |
[<xsl:apply-templates select="." mode="checkDeprecated"/>global::ProtoBuf.ProtoMember(<xsl:value-of select="number"/>, Name=@"<xsl:value-of select="name"/>", DataFormat = global::ProtoBuf.DataFormat.<xsl:value-of select="$format"/><xsl:if test="options/packed='true'">, Options = global::ProtoBuf.MemberSerializationOptions.Packed</xsl:if>)]<!-- | |
--><xsl:if test="$optionDataContract"> | |
[global::System.Runtime.Serialization.DataMember(Name=@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>, IsRequired = false)] | |
</xsl:if><xsl:if test="$optionXml"> | |
[global::System.Xml.Serialization.XmlElement(@"<xsl:value-of select="name"/>", Order = <xsl:value-of select="number"/>)] | |
</xsl:if> | |
public global::System.Collections.Generic.List<<xsl:value-of select="$type" />> <xsl:call-template name="pascal"/> | |
{ | |
get { return <xsl:value-of select="$field"/>; }<!-- | |
--><xsl:if test="$optionXml"> | |
set { <xsl:value-of select="$field"/> = value; }</xsl:if> | |
} | |
</xsl:template> | |
<xsl:template match="ServiceDescriptorProto"> | |
<xsl:if test="($optionClientProxy or $optionDataContract)"> | |
[global::System.ServiceModel.ServiceContract(Name = @"<xsl:value-of select="name"/>")]</xsl:if> | |
public interface I<xsl:value-of select="name"/> | |
{ | |
<xsl:apply-templates select="method"/> | |
} | |
<xsl:if test="$optionProtoRpc"> | |
public class <xsl:value-of select="name"/>Client : global::ProtoBuf.ServiceModel.RpcClient | |
{ | |
public <xsl:value-of select="name"/>Client() : base(typeof(I<xsl:value-of select="name"/>)) { } | |
<xsl:apply-templates select="method/MethodDescriptorProto" mode="protoRpc"/> | |
} | |
</xsl:if> | |
<xsl:apply-templates select="." mode="clientProxy"/> | |
</xsl:template> | |
<xsl:template match="MethodDescriptorProto"> | |
<xsl:if test="($optionClientProxy or $optionDataContract)"> | |
[global::System.ServiceModel.OperationContract(Name = @"<xsl:value-of select="name"/>")] | |
<xsl:if test="$optionFullFramework">[global::ProtoBuf.ServiceModel.ProtoBehavior]</xsl:if> | |
</xsl:if> | |
<xsl:apply-templates select="output_type"/><xsl:text xml:space="preserve"> </xsl:text><xsl:value-of select="name"/>(<xsl:apply-templates select="input_type"/> request); | |
<xsl:if test="$optionAsynchronous and ($optionClientProxy or $optionDataContract)"> | |
[global::System.ServiceModel.OperationContract(AsyncPattern = true, Name = @"<xsl:value-of select="name"/>")] | |
global::System.IAsyncResult Begin<xsl:value-of select="name"/>(<xsl:apply-templates select="input_type"/> request, global::System.AsyncCallback callback, object state); | |
<xsl:apply-templates select="output_type"/> End<xsl:value-of select="name"/>(global::System.IAsyncResult ar); | |
</xsl:if> | |
</xsl:template> | |
<xsl:template match="MethodDescriptorProto" mode="protoRpc"> | |
<xsl:apply-templates select="output_type"/><xsl:text xml:space="preserve"> </xsl:text><xsl:value-of select="name"/>(<xsl:apply-templates select="input_type"/> request) | |
{ | |
return (<xsl:apply-templates select="output_type"/>) Send(@"<xsl:value-of select="name"/>", request); | |
} | |
</xsl:template> | |
<xsl:template match="MethodDescriptorProto/input_type | MethodDescriptorProto/output_type"> | |
<xsl:value-of select="substring-after(.,'.')"/> | |
</xsl:template> | |
<xsl:template match="MethodDescriptorProto" mode="CompleteEvent"> | |
<xsl:if test="$optionAsynchronous and $optionDataContract"> | |
public partial class <xsl:value-of select="name"/>CompletedEventArgs : global::System.ComponentModel.AsyncCompletedEventArgs | |
{ | |
private object[] results; | |
public <xsl:value-of select="name"/>CompletedEventArgs(object[] results, global::System.Exception exception, bool cancelled, object userState) | |
: base(exception, cancelled, userState) | |
{ | |
this.results = results; | |
} | |
public <xsl:apply-templates select="output_type"/> Result | |
{ | |
get { | |
base.RaiseExceptionIfNecessary(); | |
return (<xsl:apply-templates select="output_type"/>)(this.results[0]); | |
} | |
} | |
} | |
</xsl:if> | |
</xsl:template> | |
<xsl:template match="ServiceDescriptorProto" mode="clientProxy"> | |
<xsl:if test="$optionAsynchronous and $optionDataContract and $optionClientProxy"> | |
<xsl:apply-templates select="method/MethodDescriptorProto" mode="CompleteEvent"/> | |
[global::System.Diagnostics.DebuggerStepThroughAttribute()] | |
public partial class <xsl:value-of select="name"/>Client : global::System.ServiceModel.ClientBase<I<xsl:value-of select="name"/>>, I<xsl:value-of select="name"/> | |
{ | |
public <xsl:value-of select="name"/>Client() | |
{} | |
public <xsl:value-of select="name"/>Client(string endpointConfigurationName) | |
: base(endpointConfigurationName) | |
{} | |
public <xsl:value-of select="name"/>Client(string endpointConfigurationName, string remoteAddress) | |
: base(endpointConfigurationName, remoteAddress) | |
{} | |
public <xsl:value-of select="name"/>Client(string endpointConfigurationName, global::System.ServiceModel.EndpointAddress remoteAddress) | |
: base(endpointConfigurationName, remoteAddress) | |
{} | |
public <xsl:value-of select="name"/>Client(global::System.ServiceModel.Channels.Binding binding, global::System.ServiceModel.EndpointAddress remoteAddress) | |
: base(binding, remoteAddress) | |
{} | |
<xsl:apply-templates select="method/MethodDescriptorProto" mode="clientProxy"/> | |
} | |
</xsl:if> | |
</xsl:template> | |
<xsl:template match="MethodDescriptorProto" mode="clientProxy"> | |
<xsl:if test="$optionAsynchronous and $optionDataContract and $optionClientProxy"> | |
private BeginOperationDelegate onBegin<xsl:value-of select="name"/>Delegate; | |
private EndOperationDelegate onEnd<xsl:value-of select="name"/>Delegate; | |
private global::System.Threading.SendOrPostCallback on<xsl:value-of select="name"/>CompletedDelegate; | |
public event global::System.EventHandler<<xsl:value-of select="name"/>CompletedEventArgs> <xsl:value-of select="name"/>Completed; | |
public <xsl:apply-templates select="output_type"/><xsl:text xml:space="preserve"> </xsl:text><xsl:value-of select="name"/>(<xsl:apply-templates select="input_type"/> request) | |
{ | |
return base.Channel.<xsl:value-of select="name"/>(request); | |
} | |
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |
public global::System.IAsyncResult Begin<xsl:value-of select="name"/>(<xsl:apply-templates select="input_type"/> request, global::System.AsyncCallback callback, object asyncState) | |
{ | |
return base.Channel.Begin<xsl:value-of select="name"/>(request, callback, asyncState); | |
} | |
[global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] | |
public <xsl:apply-templates select="output_type"/> End<xsl:value-of select="name"/>(global::System.IAsyncResult result) | |
{ | |
return base.Channel.End<xsl:value-of select="name"/>(result); | |
} | |
private global::System.IAsyncResult OnBegin<xsl:value-of select="name"/>(object[] inValues, global::System.AsyncCallback callback, object asyncState) | |
{ | |
<xsl:apply-templates select="input_type"/> request = ((<xsl:apply-templates select="input_type"/>)(inValues[0])); | |
return this.Begin<xsl:value-of select="name"/>(request, callback, asyncState); | |
} | |
private object[] OnEnd<xsl:value-of select="name"/>(global::System.IAsyncResult result) | |
{ | |
<xsl:apply-templates select="output_type"/> retVal = this.End<xsl:value-of select="name"/>(result); | |
return new object[] { | |
retVal}; | |
} | |
private void On<xsl:value-of select="name"/>Completed(object state) | |
{ | |
if ((this.<xsl:value-of select="name"/>Completed != null)) | |
{ | |
InvokeAsyncCompletedEventArgs e = ((InvokeAsyncCompletedEventArgs)(state)); | |
this.<xsl:value-of select="name"/>Completed(this, new <xsl:value-of select="name"/>CompletedEventArgs(e.Results, e.Error, e.Cancelled, e.UserState)); | |
} | |
} | |
public void <xsl:value-of select="name"/>Async(<xsl:apply-templates select="input_type"/> request) | |
{ | |
this.<xsl:value-of select="name"/>Async(request, null); | |
} | |
public void <xsl:value-of select="name"/>Async(<xsl:apply-templates select="input_type"/> request, object userState) | |
{ | |
if ((this.onBegin<xsl:value-of select="name"/>Delegate == null)) | |
{ | |
this.onBegin<xsl:value-of select="name"/>Delegate = new BeginOperationDelegate(this.OnBegin<xsl:value-of select="name"/>); | |
} | |
if ((this.onEnd<xsl:value-of select="name"/>Delegate == null)) | |
{ | |
this.onEnd<xsl:value-of select="name"/>Delegate = new EndOperationDelegate(this.OnEnd<xsl:value-of select="name"/>); | |
} | |
if ((this.on<xsl:value-of select="name"/>CompletedDelegate == null)) | |
{ | |
this.on<xsl:value-of select="name"/>CompletedDelegate = new global::System.Threading.SendOrPostCallback(this.On<xsl:value-of select="name"/>Completed); | |
} | |
base.InvokeAsync(this.onBegin<xsl:value-of select="name"/>Delegate, new object[] { | |
request}, this.onEnd<xsl:value-of select="name"/>Delegate, this.on<xsl:value-of select="name"/>CompletedDelegate, userState); | |
} | |
</xsl:if> | |
</xsl:template> | |
</xsl:stylesheet> |
In conjunction with the patch for issue 72
https://code.google.com/p/protobuf-net/issues/detail?id=72
This file can make the current implementation of the Protobuf-net tools useful. Without these however protobuf-net is full of surprises like:
- Requiring you to specify if it should detect missing values (why is this not always on?)
- Not being able to identify between not specified (null in every other computer system) and the default value
- Not being able to compile if an Enum is optional but does not specify a default value?!
- Happily serializing invalid messages i.e. where required values are missing
In conjunction with the patch for issue 72
https://code.google.com/p/protobuf-net/issues/detail?id=72
This file can make the current implementation of the Protobuf-net tools useful. Without these however protobuf-net is full of surprises like:
- Requiring you to specify if it should detect missing values (why is this not always on?)
- Not being able to identify between not specified (null in every other computer system) and the default value
- Not being able to compile if an Enum is optional but does not specify a default value?!
- Happily serializing invalid messages i.e. where required values are missing
In conjunction with the patch for issue 72
https://code.google.com/p/protobuf-net/issues/detail?id=72
This file can make the current implementation of the Protobuf-net tools useful. Without these however protobuf-net is full of surprises like:
- Requiring you to specify if it should detect missing values (why is this not always on?)
- Not being able to identify between not specified (null in every other computer system) and the default value
- Not being able to compile if an Enum is optional but does not specify a default value?!
- Happily serializing invalid messages i.e. where required values are missing
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
With this file and then the patch that has been provided (but not implemented) for issue 72
https://code.google.com/p/protobuf-net/issues/detail?id=72
protobuf-net starts to become useful. It leverages language features like