public void LookupAmqpMethod(MethodInfo method, string methodName, out AmqpClass amqpClass, out AmqpMethod amqpMethod) { amqpClass = null; amqpMethod = null; // First, try autodetecting the class/method via the // IModel method name. foreach (AmqpClass c in m_classes) { foreach (AmqpMethod m in c.m_Methods) { if (methodName.Equals(MangleMethodClass(c, m))) { amqpClass = c; amqpMethod = m; goto stopSearching; // wheee } } } stopSearching: // If an explicit mapping was provided as an attribute, // then use that instead, whether the autodetect worked or // not. { AmqpMethodMappingAttribute methodMapping = Attribute(method, typeof(AmqpMethodMappingAttribute)) as AmqpMethodMappingAttribute; if (methodMapping != null) { amqpClass = null; foreach (AmqpClass c in m_classes) { if (c.Name == methodMapping.m_className) { amqpClass = c; break; } } amqpMethod = amqpClass.MethodNamed(methodMapping.m_methodName); } } // At this point, if can't find either the class or the // method, we can't proceed. Complain. if (amqpClass == null || amqpMethod == null) { throw new Exception("Could not find AMQP class or method for IModel method " + method.Name); } }
public bool HasFactoryMethod(AmqpClass c) { foreach (Type t in m_modelTypes) { foreach (MethodInfo method in t.GetMethods()) { AmqpContentHeaderFactoryAttribute f = (AmqpContentHeaderFactoryAttribute) Attribute(method, typeof(AmqpContentHeaderFactoryAttribute)); if (f != null && MangleClass(f.m_contentClass) == MangleClass(c.Name)) { return(true); } } } return(false); }
public void EmitClassMethods(AmqpClass c) { foreach (AmqpMethod m in c.m_Methods) { EmitAutogeneratedSummary(" ", "AMQP specification method \"" + c.Name + "." + m.Name + "\"."); EmitSpecComment(m.DocumentationCommentVariant(" ", "remarks")); EmitLine(" public interface I" + MangleMethodClass(c, m) + ": IMethod {"); foreach (AmqpField f in m.m_Fields) { EmitSpecComment(f.DocumentationComment(" ")); EmitLine(" " + MapDomain(f.Domain) + " " + MangleClass(f.Name) + " { get; }"); } EmitLine(" }"); } }
public void LookupAmqpMethod(MethodInfo method, string methodName, out AmqpClass amqpClass, out AmqpMethod amqpMethod) { amqpClass = null; amqpMethod = null; // First, try autodetecting the class/method via the // IModel method name. foreach (AmqpClass c in m_classes) { foreach (AmqpMethod m in c.m_Methods) { if (methodName.Equals(MangleMethodClass(c,m))) { amqpClass = c; amqpMethod = m; goto stopSearching; // wheee } } } stopSearching: // If an explicit mapping was provided as an attribute, // then use that instead, whether the autodetect worked or // not. { AmqpMethodMappingAttribute methodMapping = Attribute(method, typeof(AmqpMethodMappingAttribute)) as AmqpMethodMappingAttribute; if (methodMapping != null) { amqpClass = null; foreach (AmqpClass c in m_classes) { if (c.Name == methodMapping.m_className) { amqpClass = c; break; } } amqpMethod = amqpClass.MethodNamed(methodMapping.m_methodName); } } // At this point, if can't find either the class or the // method, we can't proceed. Complain. if (amqpClass == null || amqpMethod == null) { throw new Exception("Could not find AMQP class or method for IModel method " + method.Name); } }
public void EmitClassMethodImplementations(AmqpClass c) { foreach (AmqpMethod m in c.m_Methods) { EmitAutogeneratedSummary(" ", "Private implementation class - do not use directly."); EmitLine(" public class "+MangleMethodClass(c,m) +": RabbitMQ.Client.Impl.MethodBase, I"+MangleMethodClass(c,m)+" {"); EmitLine(" public const int ClassId = "+c.Index+";"); EmitLine(" public const int MethodId = "+m.Index+";"); EmitLine(""); foreach (AmqpField f in m.m_Fields) { EmitLine(" public "+MapDomain(f.Domain)+" m_"+MangleMethod(f.Name)+";"); } EmitLine(""); foreach (AmqpField f in m.m_Fields) { EmitLine(" "+MapDomain(f.Domain)+" I"+MangleMethodClass(c,m)+ "."+MangleClass(f.Name)+" { get {" + " return m_" + MangleMethod(f.Name) + "; } }"); } EmitLine(""); if (m.m_Fields.Count > 0) { EmitLine(" public "+MangleMethodClass(c,m)+"() {}"); } EmitLine(" public "+MangleMethodClass(c,m)+"("); { int remaining = m.m_Fields.Count; foreach (AmqpField f in m.m_Fields) { Emit(" "+MapDomain(f.Domain)+" init"+MangleClass(f.Name)); remaining--; if (remaining > 0) { EmitLine(","); } } } EmitLine(")"); EmitLine(" {"); foreach (AmqpField f in m.m_Fields) { EmitLine(" m_" + MangleMethod(f.Name) + " = init" + MangleClass(f.Name) + ";"); } EmitLine(" }"); EmitLine(""); EmitLine(" public override int ProtocolClassId { get { return "+c.Index+"; } }"); EmitLine(" public override int ProtocolMethodId { get { return "+m.Index+"; } }"); EmitLine(" public override string ProtocolMethodName { get { return \""+c.Name+"."+m.Name+"\"; } }"); EmitLine(" public override bool HasContent { get { return " +(m.HasContent ? "true" : "false")+"; } }"); EmitLine(""); EmitLine(" public override void ReadArgumentsFrom(RabbitMQ.Client.Impl.MethodArgumentReader reader) {"); foreach (AmqpField f in m.m_Fields) { EmitLine(" m_" + MangleMethod(f.Name) + " = reader.Read" + MangleClass(ResolveDomain(f.Domain)) + "();"); } EmitLine(" }"); EmitLine(""); EmitLine(" public override void WriteArgumentsTo(RabbitMQ.Client.Impl.MethodArgumentWriter writer) {"); foreach (AmqpField f in m.m_Fields) { EmitLine(" writer.Write"+MangleClass(ResolveDomain(f.Domain)) + "(m_" + MangleMethod(f.Name) + ");"); } EmitLine(" }"); EmitLine(""); EmitLine(" public override void AppendArgumentDebugStringTo(System.Text.StringBuilder sb) {"); EmitLine(" sb.Append(\"(\");"); { int remaining = m.m_Fields.Count; foreach (AmqpField f in m.m_Fields) { Emit(" sb.Append(m_" + MangleMethod(f.Name) + ");"); remaining--; if (remaining > 0) { EmitLine(" sb.Append(\",\");"); } else { EmitLine(""); } } } EmitLine(" sb.Append(\")\");"); EmitLine(" }"); EmitLine(" }"); } }
public void EmitClassProperties(AmqpClass c) { bool hasCommonApi = HasFactoryMethod(c); string propertiesBaseClass = hasCommonApi ? "RabbitMQ.Client.Impl."+MangleClass(c.Name)+"Properties" : "RabbitMQ.Client.Impl.ContentHeaderBase"; string maybeOverride = hasCommonApi ? "override " : ""; EmitAutogeneratedSummary(" ", "AMQP specification content header properties for "+ "content class \""+c.Name+"\""); EmitSpecComment(c.DocumentationCommentVariant(" ", "remarks")); EmitLine(" public class "+MangleClass(c.Name) +"Properties: "+propertiesBaseClass+" {"); foreach (AmqpField f in c.m_Fields) { EmitLine(" private "+MapDomain(f.Domain)+" m_"+MangleMethod(f.Name)+";"); } EmitLine(""); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" private bool m_"+MangleMethod(f.Name)+"_present = false;"); } } EmitLine(""); foreach (AmqpField f in c.m_Fields) { EmitSpecComment(f.DocumentationComment(" ", "@label")); EmitLine(" public "+maybeOverride+MapDomain(f.Domain)+" "+MangleClass(f.Name)+" {"); EmitLine(" get {"); EmitLine(" return m_"+MangleMethod(f.Name)+";"); EmitLine(" }"); EmitLine(" set {"); if (!IsBoolean(f)) { EmitLine(" m_"+MangleMethod(f.Name)+"_present = true;"); } EmitLine(" m_"+MangleMethod(f.Name)+" = value;"); EmitLine(" }"); EmitLine(" }"); } EmitLine(""); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" public "+maybeOverride+"void Clear"+MangleClass(f.Name)+"() { m_"+MangleMethod(f.Name)+"_present = false; }"); } } EmitLine(""); EmitLine(" public "+MangleClass(c.Name)+"Properties() {}"); EmitLine(" public override int ProtocolClassId { get { return "+c.Index+"; } }"); EmitLine(" public override string ProtocolClassName { get { return \""+c.Name+"\"; } }"); EmitLine(""); EmitLine(" public override void ReadPropertiesFrom(RabbitMQ.Client.Impl.ContentHeaderPropertyReader reader) {"); foreach (AmqpField f in c.m_Fields) { if (IsBoolean(f)) { EmitLine(" m_"+MangleMethod(f.Name)+" = reader.ReadBit();"); } else { EmitLine(" m_"+MangleMethod(f.Name)+"_present = reader.ReadPresence();"); } } EmitLine(" reader.FinishPresence();"); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" if (m_"+MangleMethod(f.Name)+"_present) { m_"+MangleMethod(f.Name)+" = reader.Read"+MangleClass(ResolveDomain(f.Domain))+"(); }"); } } EmitLine(" }"); EmitLine(""); EmitLine(" public override void WritePropertiesTo(RabbitMQ.Client.Impl.ContentHeaderPropertyWriter writer) {"); foreach (AmqpField f in c.m_Fields) { if (IsBoolean(f)) { EmitLine(" writer.WriteBit(m_"+MangleMethod(f.Name)+");"); } else { EmitLine(" writer.WritePresence(m_"+MangleMethod(f.Name)+"_present);"); } } EmitLine(" writer.FinishPresence();"); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" if (m_"+MangleMethod(f.Name)+"_present) { writer.Write"+MangleClass(ResolveDomain(f.Domain))+"(m_"+MangleMethod(f.Name)+"); }"); } } EmitLine(" }"); EmitLine(""); EmitLine(" public override void AppendPropertyDebugStringTo(System.Text.StringBuilder sb) {"); EmitLine(" sb.Append(\"(\");"); { int remaining = c.m_Fields.Count; foreach (AmqpField f in c.m_Fields) { Emit(" sb.Append(\""+f.Name+"=\");"); if (IsBoolean(f)) { Emit(" sb.Append(m_"+MangleMethod(f.Name)+");"); } else { string x = MangleMethod(f.Name); if (IsReferenceType(f)) { Emit(" sb.Append(m_"+x+"_present ? (m_"+x+" == null ? \"(null)\" : m_"+x+".ToString()) : \"_\");"); } else { Emit(" sb.Append(m_"+x+"_present ? m_"+x+".ToString() : \"_\");"); } } remaining--; if (remaining > 0) { EmitLine(" sb.Append(\", \");"); } else { EmitLine(""); } } } EmitLine(" sb.Append(\")\");"); EmitLine(" }"); EmitLine(" }"); }
public bool HasFactoryMethod(AmqpClass c) { foreach (Type t in m_modelTypes) { foreach (MethodInfo method in t.GetMethods()) { AmqpContentHeaderFactoryAttribute f = (AmqpContentHeaderFactoryAttribute) Attribute(method, typeof(AmqpContentHeaderFactoryAttribute)); if (f != null && MangleClass(f.m_contentClass) == MangleClass(c.Name)) { return true; } } } return false; }
public void EmitClassMethods(AmqpClass c) { foreach (AmqpMethod m in c.m_Methods) { EmitAutogeneratedSummary(" ", "AMQP specification method \""+c.Name+"."+m.Name+"\"."); EmitSpecComment(m.DocumentationCommentVariant(" ", "remarks")); EmitLine(" public interface I"+MangleMethodClass(c, m)+": IMethod {"); foreach (AmqpField f in m.m_Fields) { EmitSpecComment(f.DocumentationComment(" ")); EmitLine(" "+MapDomain(f.Domain)+" "+MangleClass(f.Name)+" { get; }"); } EmitLine(" }"); } }
public static string MangleMethodClass(AmqpClass c, AmqpMethod m) { return MangleClass(c.Name) + MangleClass(m.Name); }
public void EmitClassMethodImplementations(AmqpClass c) { foreach (AmqpMethod m in c.m_Methods) { EmitAutogeneratedSummary(" ", "Private implementation class - do not use directly."); EmitLine(" public class " + MangleMethodClass(c, m) + ": RabbitMQ.Client.Impl.MethodBase, I" + MangleMethodClass(c, m) + " {"); EmitLine(" public const int ClassId = " + c.Index + ";"); EmitLine(" public const int MethodId = " + m.Index + ";"); EmitLine(""); foreach (AmqpField f in m.m_Fields) { EmitLine(" public " + MapDomain(f.Domain) + " m_" + MangleMethod(f.Name) + ";"); } EmitLine(""); foreach (AmqpField f in m.m_Fields) { EmitLine(" " + MapDomain(f.Domain) + " I" + MangleMethodClass(c, m) + "." + MangleClass(f.Name) + " { get {" + " return m_" + MangleMethod(f.Name) + "; } }"); } EmitLine(""); if (m.m_Fields.Count > 0) { EmitLine(" public " + MangleMethodClass(c, m) + "() {}"); } EmitLine(" public " + MangleMethodClass(c, m) + "("); { int remaining = m.m_Fields.Count; foreach (AmqpField f in m.m_Fields) { Emit(" " + MapDomain(f.Domain) + " init" + MangleClass(f.Name)); remaining--; if (remaining > 0) { EmitLine(","); } } } EmitLine(")"); EmitLine(" {"); foreach (AmqpField f in m.m_Fields) { EmitLine(" m_" + MangleMethod(f.Name) + " = init" + MangleClass(f.Name) + ";"); } EmitLine(" }"); EmitLine(""); EmitLine(" public override int ProtocolClassId { get { return " + c.Index + "; } }"); EmitLine(" public override int ProtocolMethodId { get { return " + m.Index + "; } }"); EmitLine(" public override string ProtocolMethodName { get { return \"" + c.Name + "." + m.Name + "\"; } }"); EmitLine(" public override bool HasContent { get { return " + (m.HasContent ? "true" : "false") + "; } }"); EmitLine(""); EmitLine(" public override void ReadArgumentsFrom(RabbitMQ.Client.Impl.MethodArgumentReader reader) {"); foreach (AmqpField f in m.m_Fields) { EmitLine(" m_" + MangleMethod(f.Name) + " = reader.Read" + MangleClass(ResolveDomain(f.Domain)) + "();"); } EmitLine(" }"); EmitLine(""); EmitLine(" public override void WriteArgumentsTo(RabbitMQ.Client.Impl.MethodArgumentWriter writer) {"); foreach (AmqpField f in m.m_Fields) { EmitLine(" writer.Write" + MangleClass(ResolveDomain(f.Domain)) + "(m_" + MangleMethod(f.Name) + ");"); } EmitLine(" }"); EmitLine(""); EmitLine(" public override void AppendArgumentDebugStringTo(System.Text.StringBuilder sb) {"); EmitLine(" sb.Append(\"(\");"); { int remaining = m.m_Fields.Count; foreach (AmqpField f in m.m_Fields) { Emit(" sb.Append(m_" + MangleMethod(f.Name) + ");"); remaining--; if (remaining > 0) { EmitLine(" sb.Append(\",\");"); } else { EmitLine(""); } } } EmitLine(" sb.Append(\")\");"); EmitLine(" }"); EmitLine(" }"); } }
public void EmitClassProperties(AmqpClass c) { bool hasCommonApi = HasFactoryMethod(c); string propertiesBaseClass = hasCommonApi ? "RabbitMQ.Client.Impl." + MangleClass(c.Name) + "Properties" : "RabbitMQ.Client.Impl.ContentHeaderBase"; string maybeOverride = hasCommonApi ? "override " : ""; EmitAutogeneratedSummary(" ", "AMQP specification content header properties for " + "content class \"" + c.Name + "\""); EmitSpecComment(c.DocumentationCommentVariant(" ", "remarks")); EmitLine(" public class " + MangleClass(c.Name) + "Properties: " + propertiesBaseClass + " {"); foreach (AmqpField f in c.m_Fields) { EmitLine(" private " + MapDomain(f.Domain) + " m_" + MangleMethod(f.Name) + ";"); } EmitLine(""); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" private bool m_" + MangleMethod(f.Name) + "_present = false;"); } } EmitLine(""); foreach (AmqpField f in c.m_Fields) { EmitSpecComment(f.DocumentationComment(" ", "@label")); EmitLine(" public " + maybeOverride + MapDomain(f.Domain) + " " + MangleClass(f.Name) + " {"); EmitLine(" get {"); EmitLine(" return m_" + MangleMethod(f.Name) + ";"); EmitLine(" }"); EmitLine(" set {"); if (!IsBoolean(f)) { EmitLine(" m_" + MangleMethod(f.Name) + "_present = true;"); } EmitLine(" m_" + MangleMethod(f.Name) + " = value;"); EmitLine(" }"); EmitLine(" }"); } EmitLine(""); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" public " + maybeOverride + "void Clear" + MangleClass(f.Name) + "() { m_" + MangleMethod(f.Name) + "_present = false; }"); } } EmitLine(""); EmitLine(" public " + MangleClass(c.Name) + "Properties() {}"); EmitLine(" public override int ProtocolClassId { get { return " + c.Index + "; } }"); EmitLine(" public override string ProtocolClassName { get { return \"" + c.Name + "\"; } }"); EmitLine(""); EmitLine(" public override void ReadPropertiesFrom(RabbitMQ.Client.Impl.ContentHeaderPropertyReader reader) {"); foreach (AmqpField f in c.m_Fields) { if (IsBoolean(f)) { EmitLine(" m_" + MangleMethod(f.Name) + " = reader.ReadBit();"); } else { EmitLine(" m_" + MangleMethod(f.Name) + "_present = reader.ReadPresence();"); } } EmitLine(" reader.FinishPresence();"); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" if (m_" + MangleMethod(f.Name) + "_present) { m_" + MangleMethod(f.Name) + " = reader.Read" + MangleClass(ResolveDomain(f.Domain)) + "(); }"); } } EmitLine(" }"); EmitLine(""); EmitLine(" public override void WritePropertiesTo(RabbitMQ.Client.Impl.ContentHeaderPropertyWriter writer) {"); foreach (AmqpField f in c.m_Fields) { if (IsBoolean(f)) { EmitLine(" writer.WriteBit(m_" + MangleMethod(f.Name) + ");"); } else { EmitLine(" writer.WritePresence(m_" + MangleMethod(f.Name) + "_present);"); } } EmitLine(" writer.FinishPresence();"); foreach (AmqpField f in c.m_Fields) { if (!IsBoolean(f)) { EmitLine(" if (m_" + MangleMethod(f.Name) + "_present) { writer.Write" + MangleClass(ResolveDomain(f.Domain)) + "(m_" + MangleMethod(f.Name) + "); }"); } } EmitLine(" }"); EmitLine(""); EmitLine(" public override void AppendPropertyDebugStringTo(System.Text.StringBuilder sb) {"); EmitLine(" sb.Append(\"(\");"); { int remaining = c.m_Fields.Count; foreach (AmqpField f in c.m_Fields) { Emit(" sb.Append(\"" + f.Name + "=\");"); if (IsBoolean(f)) { Emit(" sb.Append(m_" + MangleMethod(f.Name) + ");"); } else { string x = MangleMethod(f.Name); if (IsReferenceType(f)) { Emit(" sb.Append(m_" + x + "_present ? (m_" + x + " == null ? \"(null)\" : m_" + x + ".ToString()) : \"_\");"); } else { Emit(" sb.Append(m_" + x + "_present ? m_" + x + ".ToString() : \"_\");"); } } remaining--; if (remaining > 0) { EmitLine(" sb.Append(\", \");"); } else { EmitLine(""); } } } EmitLine(" sb.Append(\")\");"); EmitLine(" }"); EmitLine(" }"); }
public static string MangleMethodClass(AmqpClass c, AmqpMethod m) { return(MangleClass(c.Name) + MangleClass(m.Name)); }
public void EmitAsynchronousHandlers(ArrayList asynchronousHandlers) { EmitLine(" public override bool DispatchAsynchronous(RabbitMQ.Client.Impl.Command cmd) {"); EmitLine(" RabbitMQ.Client.Impl.MethodBase __method = (RabbitMQ.Client.Impl.MethodBase) cmd.Method;"); EmitLine(" switch ((__method.ProtocolClassId << 16) | __method.ProtocolMethodId) {"); foreach (MethodInfo method in asynchronousHandlers) { string methodName = method.Name; if (methodName.StartsWith("Handle")) { methodName = methodName.Substring(6); } AmqpClass amqpClass = null; AmqpMethod amqpMethod = null; LookupAmqpMethod(method, methodName, out amqpClass, out amqpMethod); string implClass = MangleMethodClass(amqpClass, amqpMethod); EmitLine(" case " + ((amqpClass.Index << 16) | amqpMethod.Index) + ": {"); ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length > 0) { EmitLine(" " + implClass + " __impl = (" + implClass + ") __method;"); EmitLine(" " + method.Name + "("); int remaining = parameters.Length; foreach (ParameterInfo pi in parameters) { if (Attribute(pi, typeof(AmqpContentHeaderMappingAttribute)) != null) { Emit(" (" + pi.ParameterType + ") cmd.Header"); } else if (Attribute(pi, typeof(AmqpContentBodyMappingAttribute)) != null) { Emit(" cmd.Body"); } else { AmqpFieldMappingAttribute fieldMapping = Attribute(pi, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute; Emit(" __impl.m_" + (fieldMapping == null ? pi.Name : fieldMapping.m_fieldName)); } remaining--; if (remaining > 0) { EmitLine(","); } } EmitLine(");"); } else { EmitLine(" " + method.Name + "();"); } EmitLine(" return true;"); EmitLine(" }"); } EmitLine(" default: return false;"); EmitLine(" }"); EmitLine(" }"); }
public void EmitModelMethod(MethodInfo method) { ParameterInfo[] parameters = method.GetParameters(); AmqpClass amqpClass = null; AmqpMethod amqpMethod = null; LookupAmqpMethod(method, method.Name, out amqpClass, out amqpMethod); string requestImplClass = MangleMethodClass(amqpClass, amqpMethod); // At this point, we know which request method to // send. Now compute whether it's an RPC or not. AmqpMethod amqpReplyMethod = null; AmqpMethodMappingAttribute replyMapping = Attribute(method.ReturnTypeCustomAttributes, typeof(AmqpMethodMappingAttribute)) as AmqpMethodMappingAttribute; if (Attribute(method, typeof(AmqpForceOneWayAttribute)) == null && (amqpMethod.IsSimpleRpcRequest || replyMapping != null)) { // We're not forcing oneway, and either are a simple // RPC request, or have an explicit replyMapping amqpReplyMethod = amqpClass.MethodNamed(replyMapping == null ? (string)amqpMethod.m_ResponseMethods[0] : replyMapping.m_methodName); if (amqpReplyMethod == null) { throw new Exception("Could not find AMQP reply method for IModel method " + method.Name); } } // If amqpReplyMethod is null at this point, it's a // one-way operation, and no continuation needs to be // consed up. Otherwise, we should expect a reply of kind // identified by amqpReplyMethod - unless there's a nowait // parameter thrown into the equation! // // Examine the parameters to discover which might be // nowait, content header or content body. ParameterInfo nowaitParameter = null; string nowaitExpression = "null"; ParameterInfo contentHeaderParameter = null; ParameterInfo contentBodyParameter = null; foreach (ParameterInfo pi in parameters) { AmqpNowaitArgumentAttribute nwAttr = Attribute(pi, typeof(AmqpNowaitArgumentAttribute)) as AmqpNowaitArgumentAttribute; if (nwAttr != null) { nowaitParameter = pi; if (nwAttr.m_replacementExpression != null) { nowaitExpression = nwAttr.m_replacementExpression; } } if (Attribute(pi, typeof(AmqpContentHeaderMappingAttribute)) != null) { contentHeaderParameter = pi; } if (Attribute(pi, typeof(AmqpContentBodyMappingAttribute)) != null) { contentBodyParameter = pi; } } // Compute expression text for the content header and body. string contentHeaderExpr = contentHeaderParameter == null ? "null" : " (" + MangleClass(amqpClass.Name) + "Properties) " + contentHeaderParameter.Name; string contentBodyExpr = contentBodyParameter == null ? "null" : contentBodyParameter.Name; // Emit the method declaration and preamble. EmitModelMethodPreamble(method); EmitLine(" {"); // Emit the code to build the request. EmitLine(" " + requestImplClass + " __req = new " + requestImplClass + "();"); foreach (ParameterInfo pi in parameters) { if (pi != contentHeaderParameter && pi != contentBodyParameter) { if (Attribute(pi, typeof(AmqpUnsupportedAttribute)) != null) { EmitLine(" if (@" + pi.Name + " != null) {"); EmitLine(" throw new UnsupportedMethodFieldException(\"" + method.Name + "\",\"" + pi.Name + "\");"); EmitLine(" }"); } else { AmqpFieldMappingAttribute fieldMapping = Attribute(pi, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute; if (fieldMapping != null) { EmitLine(" __req.m_" + fieldMapping.m_fieldName + " = @" + pi.Name + ";"); } else { EmitLine(" __req.m_" + pi.Name + " = @" + pi.Name + ";"); } } } } // If we have a nowait parameter, sometimes that can turn // a ModelRpc call into a ModelSend call. if (nowaitParameter != null) { EmitLine(" if (" + nowaitParameter.Name + ") {"); EmitLine(" ModelSend(__req," + contentHeaderExpr + "," + contentBodyExpr + ");"); if (method.ReturnType != typeof(void)) { EmitLine(" return " + nowaitExpression + ";"); } EmitLine(" }"); } // At this point, perform either a ModelRpc or a // ModelSend. if (amqpReplyMethod == null) { EmitLine(" ModelSend(__req," + contentHeaderExpr + "," + contentBodyExpr + ");"); } else { string replyImplClass = MangleMethodClass(amqpClass, amqpReplyMethod); EmitLine(" RabbitMQ.Client.Impl.MethodBase __repBase = ModelRpc(__req," + contentHeaderExpr + "," + contentBodyExpr + ");"); EmitLine(" " + replyImplClass + " __rep = __repBase as " + replyImplClass + ";"); EmitLine(" if (__rep == null) throw new UnexpectedMethodException(__repBase);"); if (method.ReturnType == typeof(void)) { // No need to further examine the reply. } else { // At this point, we have the reply method. Extract values from it. AmqpFieldMappingAttribute returnMapping = Attribute(method.ReturnTypeCustomAttributes, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute; if (returnMapping == null) { string fieldPrefix = IsAmqpClass(method.ReturnType) ? "m_" : ""; // No field mapping --> it's assumed to be a struct to fill in. EmitLine(" " + method.ReturnType + " __result = new " + method.ReturnType + "();"); foreach (FieldInfo fi in method.ReturnType.GetFields()) { AmqpFieldMappingAttribute returnFieldMapping = Attribute(fi, typeof(AmqpFieldMappingAttribute)) as AmqpFieldMappingAttribute; if (returnFieldMapping != null) { EmitLine(" __result." + fi.Name + " = __rep." + fieldPrefix + returnFieldMapping.m_fieldName + ";"); } else { EmitLine(" __result." + fi.Name + " = __rep." + fieldPrefix + fi.Name + ";"); } } EmitLine(" return __result;"); } else { // Field mapping --> return just the field we're interested in. EmitLine(" return __rep.m_" + returnMapping.m_fieldName + ";"); } } } // All the IO and result-extraction has been done. Emit // the method postamble. EmitLine(" }"); }