diff --git a/RabbitMQDotNetClient.sln b/RabbitMQDotNetClient.sln
index 8c7cd7253c..e7b966dc5e 100644
--- a/RabbitMQDotNetClient.sln
+++ b/RabbitMQDotNetClient.sln
@@ -12,8 +12,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RabbitMQ.Client", "projects
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Unit", "projects\Unit\Unit.csproj", "{B8FAC024-CC03-4067-9FFC-02846FB8AE48}"
EndProject
-Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Apigen", "projects\Apigen\Apigen.csproj", "{B416DDB7-5E3E-4A20-B5A9-C6E518E203A2}"
-EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -28,10 +26,6 @@ Global
{B8FAC024-CC03-4067-9FFC-02846FB8AE48}.Debug|Any CPU.Build.0 = Debug|Any CPU
{B8FAC024-CC03-4067-9FFC-02846FB8AE48}.Release|Any CPU.ActiveCfg = Release|Any CPU
{B8FAC024-CC03-4067-9FFC-02846FB8AE48}.Release|Any CPU.Build.0 = Release|Any CPU
- {B416DDB7-5E3E-4A20-B5A9-C6E518E203A2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
- {B416DDB7-5E3E-4A20-B5A9-C6E518E203A2}.Debug|Any CPU.Build.0 = Debug|Any CPU
- {B416DDB7-5E3E-4A20-B5A9-C6E518E203A2}.Release|Any CPU.ActiveCfg = Release|Any CPU
- {B416DDB7-5E3E-4A20-B5A9-C6E518E203A2}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
diff --git a/build.bat b/build.bat
index c93c305127..add2a96ff9 100644
--- a/build.bat
+++ b/build.bat
@@ -1,5 +1,4 @@
@ECHO OFF
set DOTNET_CLI_TELEMETRY_OPTOUT=1
dotnet restore .\RabbitMQDotNetClient.sln
-dotnet run -p .\projects\Apigen\Apigen.csproj --apiName:AMQP_0_9_1 .\projects\specs\amqp0-9-1.stripped.xml .\gensrc\autogenerated-api-0-9-1.cs
dotnet build .\RabbitMQDotNetClient.sln
diff --git a/projects/Apigen/Apigen.csproj b/projects/Apigen/Apigen.csproj
deleted file mode 100755
index 29c726c6f5..0000000000
--- a/projects/Apigen/Apigen.csproj
+++ /dev/null
@@ -1,12 +0,0 @@
-
-
-
- netcoreapp3.1
- Exe
-
-
-
-
-
-
-
diff --git a/projects/Apigen/apigen/AmqpEntity.cs b/projects/Apigen/apigen/AmqpEntity.cs
deleted file mode 100644
index 07b62ce45a..0000000000
--- a/projects/Apigen/apigen/AmqpEntity.cs
+++ /dev/null
@@ -1,83 +0,0 @@
-// This source code is dual-licensed under the Apache License, version
-// 2.0, and the Mozilla Public License, version 2.0.
-//
-// The APL v2.0:
-//
-//---------------------------------------------------------------------------
-// Copyright (c) 2007-2020 VMware, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//---------------------------------------------------------------------------
-//
-// The MPL v2.0:
-//
-//---------------------------------------------------------------------------
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
-//---------------------------------------------------------------------------
-
-using System.Xml;
-
-namespace RabbitMQ.Client.Apigen
-{
- public class AmqpEntity {
- public XmlNode m_node;
-
- public AmqpEntity(XmlNode n) {
- m_node = n;
- }
-
- public string GetString(string path) {
- return Apigen.GetString(m_node, path);
- }
-
- public string GetString(string path, string d) {
- return Apigen.GetString(m_node, path, d);
- }
-
- public int GetInt(string path) {
- return Apigen.GetInt(m_node, path);
- }
-
- public string Name {
- get {
- return GetString("@name");
- }
- }
-
- public string DocumentationComment(string prefixSpaces) {
- return DocumentationComment(prefixSpaces, "doc");
- }
-
- public string DocumentationCommentVariant(string prefixSpaces, string tagname) {
- return DocumentationComment(prefixSpaces, "doc", tagname);
- }
-
- public string DocumentationComment(string prefixSpaces, string docXpath) {
- return DocumentationComment(prefixSpaces, docXpath, "summary");
- }
-
- public string DocumentationComment(string prefixSpaces, string docXpath, string tagname) {
- string docStr = GetString(docXpath, "").Trim();
- if (docStr.Length > 0) {
- return $"{prefixSpaces}/// <{tagname}>\n{GetString(docXpath, "")}\n{tagname}>"
- .Replace("\n", $"\n{prefixSpaces}/// ");
- } else {
- return $"{prefixSpaces}// (no documentation)";
- }
- }
- }
-}
diff --git a/projects/Apigen/apigen/Apigen.cs b/projects/Apigen/apigen/Apigen.cs
deleted file mode 100644
index 3ccfb5590a..0000000000
--- a/projects/Apigen/apigen/Apigen.cs
+++ /dev/null
@@ -1,1460 +0,0 @@
-// This source code is dual-licensed under the Apache License, version
-// 2.0, and the Mozilla Public License, version 2.0.
-//
-// The APL v2.0:
-//
-//---------------------------------------------------------------------------
-// Copyright (c) 2007-2020 VMware, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the "License");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//---------------------------------------------------------------------------
-//
-// The MPL v2.0:
-//
-//---------------------------------------------------------------------------
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
-//---------------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Linq;
-using System.Reflection;
-using System.Text;
-using System.Xml;
-
-using RabbitMQ.Client.Apigen.Attributes;
-
-namespace RabbitMQ.Client.Apigen
-{
- public static class ApigenExtensions
- {
- public static T Attribute(this MemberInfo mi) where T : Attribute
- {
- return mi.GetCustomAttribute(false);
- }
-
- public static T Attribute(this ParameterInfo pi) where T : Attribute
- {
- return pi.GetCustomAttribute(false);
- }
-
- public static T Attribute(this ICustomAttributeProvider p) where T : Attribute
- {
- return p.GetCustomAttributes(typeof(T), false).Cast().SingleOrDefault();
- }
- }
-
- public class Apigen
- {
- ///////////////////////////////////////////////////////////////////////////
- // Entry point
-
- public static void Main(string[] args)
- {
- Apigen instance = new Apigen(new List(args));
- instance.Generate();
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // XML utilities
-
- public static XmlNodeList GetNodes(XmlNode n0, string path)
- {
- return n0.SelectNodes(path);
- }
-
- public static string GetString(XmlNode n0, string path, string d)
- {
- XmlNode n = n0.SelectSingleNode(path);
- string pathOrDefault = (n == null) ? d : n.InnerText;
- return xmlStringMapper(pathOrDefault);
- }
-
- public static string GetString(XmlNode n0, string path)
- {
- string s = GetString(n0, path, null);
- if (s == null)
- {
- throw new Exception($"Missing spec XML node: {path}");
- }
- return s;
- }
-
- public static int GetInt(XmlNode n0, string path, int d)
- {
- string s = GetString(n0, path, null);
- return (s == null) ? d : int.Parse(s);
- }
-
- public static int GetInt(XmlNode n0, string path)
- {
- return int.Parse(GetString(n0, path));
- }
-
- ///
- /// Rename all instances of an entire string from the XML spec
- ///
- /// input string from XML spec
- /// renamed string
- private static string xmlStringMapper(string xmlString)
- {
- switch (xmlString)
- {
- case "no-wait":
- return "nowait";
- default:
- return xmlString;
- }
- }
-
- ///////////////////////////////////////////////////////////////////////////
- // Name manipulation and mangling for C#
-
- public static string MangleConstant(string name)
- {
- // Previously, we used C_STYLE_CONSTANT_NAMES:
- /*
- return name
- .Replace(" ", "_")
- .Replace("-", "_").
- ToUpper();
- */
- // ... but TheseKindsOfNames are more in line with .NET style guidelines.
- return MangleClass(name);
- }
-
- public static IList IdentifierParts(string name)
- {
- IList result = new List();
- foreach (string s1 in name.Split(new char[] { '-', ' ' }))
- {
- result.Add(s1);
- }
- return result;
- }
-
- public static string MangleClass(string name)
- {
- StringBuilder sb = new StringBuilder();
- foreach (string s in IdentifierParts(name))
- {
- sb.Append(char.ToUpperInvariant(s[0]) + s.Substring(1).ToLowerInvariant());
- }
- return sb.ToString();
- }
-
- public static string MangleMethod(string name)
- {
- StringBuilder sb = new StringBuilder();
- bool useUpper = false;
- foreach (string s in IdentifierParts(name))
- {
- if (useUpper)
- {
- sb.Append(char.ToUpperInvariant(s[0]) + s.Substring(1).ToLowerInvariant());
- }
- else
- {
- sb.Append(s.ToLowerInvariant());
- useUpper = true;
- }
- }
- return sb.ToString();
- }
-
- public static string MangleMethodClass(AmqpClass c, AmqpMethod m)
- {
- return MangleClass(c.Name) + MangleClass(m.Name);
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- public string m_inputXmlFilename;
- public string m_outputFilename;
-
- public XmlDocument m_spec = null;
- public TextWriter m_outputFile = null;
-
- public int m_majorVersion;
- public int m_minorVersion;
- public int m_revision = 0;
- public string m_apiName;
- public bool m_emitComments = false;
-
- public Type m_modelType = typeof(RabbitMQ.Client.Impl.IFullModel);
- public IList m_modelTypes = new List();
- public IList> m_constants = new List>();
- public IList m_classes = new List();
- public IDictionary m_domains = new Dictionary();
-
- public static IDictionary m_primitiveTypeMap;
- public static IDictionary m_primitiveTypeFlagMap;
-
- static Apigen()
- {
- m_primitiveTypeMap = new Dictionary();
- m_primitiveTypeFlagMap = new Dictionary();
- InitPrimitiveType("octet", "byte", false);
- InitPrimitiveType("shortstr", "string", true);
- InitPrimitiveType("longstr", "byte[]", true);
- InitPrimitiveType("short", "ushort", false);
- InitPrimitiveType("long", "uint", false);
- InitPrimitiveType("longlong", "ulong", false);
- InitPrimitiveType("bit", "bool", false);
- InitPrimitiveType("table", "IDictionary", true);
- InitPrimitiveType("timestamp", "AmqpTimestamp", false);
- InitPrimitiveType("content", "byte[]", true);
- }
-
- public static void InitPrimitiveType(string amqpType, string dotnetType, bool isReference)
- {
- m_primitiveTypeMap[amqpType] = dotnetType;
- m_primitiveTypeFlagMap[amqpType] = isReference;
- }
-
- public void HandleOption(string opt)
- {
- if (opt.StartsWith("--apiName:"))
- {
- m_apiName = opt.Substring(9);
- }
- else if (opt == "-c")
- {
- m_emitComments = true;
- }
- else
- {
- Console.Error.WriteLine($"Unsupported command-line option: {opt}");
- Usage();
- }
- }
-
- public void Usage()
- {
- Console.Error.WriteLine("Usage: Apigen.exe [options ...] ");
- Console.Error.WriteLine(" Options include:");
- Console.Error.WriteLine(" --apiName:");
- Console.Error.WriteLine(" The apiName option is required.");
- Environment.Exit(1);
- }
-
- public Apigen(IList args)
- {
- while (args.Count > 0 && args[0].StartsWith("--"))
- {
- HandleOption(args[0]);
- args.RemoveAt(0);
- }
- if ((args.Count < 2)
- || (m_apiName == null))
- {
- Usage();
- }
- m_inputXmlFilename = args[0];
- m_outputFilename = args[1];
- }
-
- ///////////////////////////////////////////////////////////////////////////
-
- public static string ApiNamespaceBase => "RabbitMQ.Client.Framing";
-
- public static string ImplNamespaceBase => "RabbitMQ.Client.Framing.Impl";
-
- public void Generate()
- {
- LoadSpec();
- ParseSpec();
- ReflectModel();
- GenerateOutput();
- }
-
- public void LoadSpec()
- {
- Console.WriteLine($"* Loading spec from '{m_inputXmlFilename}'");
- m_spec = new XmlDocument();
-
- using (var stream = new FileStream(m_inputXmlFilename, FileMode.Open, FileAccess.Read))
- {
- m_spec.Load(stream);
- }
- }
-
- public void ParseSpec()
- {
- m_majorVersion = GetInt(m_spec, "/amqp/@major");
- m_minorVersion = GetInt(m_spec, "/amqp/@minor");
- m_revision = GetInt(m_spec, "/amqp/@revision");
-
- Console.WriteLine("* Parsing spec for version {0}.{1}.{2}", m_majorVersion, m_minorVersion, m_revision);
- foreach (XmlNode n in m_spec.SelectNodes("/amqp/constant"))
- {
- m_constants.Add(new KeyValuePair(GetString(n, "@name"), GetInt(n, "@value")));
- }
- foreach (XmlNode n in m_spec.SelectNodes("/amqp/class"))
- {
- m_classes.Add(new AmqpClass(n));
- }
- foreach (XmlNode n in m_spec.SelectNodes("/amqp/domain"))
- {
- m_domains[GetString(n, "@name")] = GetString(n, "@type");
- }
- }
-
- public void ReflectModel()
- {
- m_modelTypes.Add(m_modelType);
- for (int i = 0; i < m_modelTypes.Count; i++)
- {
- foreach (Type intf in m_modelTypes[i].GetInterfaces())
- {
- m_modelTypes.Add(intf);
- }
- }
- }
-
- public string ResolveDomain(string d)
- {
- while (m_domains.ContainsKey(d))
- {
- string newD = m_domains[d];
- if (d.Equals(newD))
- {
- break;
- }
-
- d = newD;
- }
- return d;
- }
-
- public string MapDomain(string d)
- {
- return m_primitiveTypeMap[ResolveDomain(d)];
- }
-
- public string VersionToken()
- {
- return $"v{m_majorVersion}_{m_minorVersion}";
- }
-
- public void GenerateOutput()
- {
- Console.WriteLine($"* Generating code into '{m_outputFilename}'");
-
- string directory = Path.GetDirectoryName(m_outputFilename);
-
- if (!Directory.Exists(directory))
- {
- Directory.CreateDirectory(directory);
- }
-
- using (var stream = new FileStream(m_outputFilename, FileMode.Create, FileAccess.Write))
- {
- m_outputFile = new StreamWriter(stream);
- EmitPrelude();
- EmitPublic();
- EmitPrivate();
- m_outputFile.Dispose();
- }
- }
-
- public void Emit(object o)
- {
- m_outputFile.Write(o);
- }
-
- public void EmitLine(object o)
- {
- m_outputFile.WriteLine(o);
- }
-
- public void EmitSpecComment(object o)
- {
- if (m_emitComments)
- {
- EmitLine(o);
- }
- }
-
- public void EmitPrelude()
- {
- const string prelude =
-@"// Autogenerated code. Do not edit.
-
-// This source code is dual-licensed under the Apache License, version
-// 2.0, and the Mozilla Public License, version 2.0.
-//
-// The APL v2.0:
-//
-//---------------------------------------------------------------------------
-// Copyright (c) 2007-2020 VMware, Inc.
-//
-// Licensed under the Apache License, Version 2.0 (the ""License"");
-// you may not use this file except in compliance with the License.
-// You may obtain a copy of the License at
-//
-// https://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an ""AS IS"" BASIS,
-// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-// See the License for the specific language governing permissions and
-// limitations under the License.
-//---------------------------------------------------------------------------
-//
-// The MPL v2.0:
-//
-//---------------------------------------------------------------------------
-// This Source Code Form is subject to the terms of the Mozilla Public
-// License, v. 2.0. If a copy of the MPL was not distributed with this
-// file, You can obtain one at https://mozilla.org/MPL/2.0/.
-//
-// Copyright (c) 2007-2020 VMware, Inc. All rights reserved.
-//---------------------------------------------------------------------------
-
-using System;
-using System.Collections.Generic;
-using System.Text;
-
-using RabbitMQ.Client;
-using RabbitMQ.Client.Exceptions;
-using RabbitMQ.Client.Framing.Impl;
-using RabbitMQ.Client.Impl;
-";
- EmitLine(prelude);
- }
-
- public void EmitPublic()
- {
- int port = GetInt(m_spec, "/amqp/@port");
- string publicVars =
-$@"namespace {ApiNamespaceBase}
-{{
- internal sealed class Protocol : {ImplNamespaceBase}.ProtocolBase
- {{
- ///Protocol major version (= {m_majorVersion})
- public override int MajorVersion => {m_majorVersion};
-
- ///Protocol minor version (= {m_minorVersion})
- public override int MinorVersion => {m_minorVersion};
-
- ///Protocol revision (= {m_revision})
- public override int Revision => {m_revision};
-
- ///Protocol API name (= {m_apiName})
- public override string ApiName => ""{m_apiName}"";
-
- ///Default TCP port (= {port})
- public override int DefaultPort => {port};
-";
-
- EmitLine("namespace RabbitMQ.Client");
- EmitLine("{");
- EmitLine(" public static class Constants");
- EmitLine(" {");
- foreach (KeyValuePair de in m_constants)
- {
- EmitLine($" ///(= {de.Value})");
- EmitLine($" public const int {MangleConstant(de.Key)} = {de.Value};");
- }
- EmitLine(" }");
- EmitLine("}");
- EmitLine(publicVars);
- EmitMethodArgumentReader();
- EmitLine("");
- EmitContentHeaderReader();
- EmitLine(" }");
- foreach (AmqpClass c in m_classes)
- {
- EmitClassMethods(c);
- }
- foreach (AmqpClass c in m_classes)
- {
- if (c.NeedsProperties)
- {
- EmitClassProperties(c);
- }
- }
- EmitLine("}");
- }
-
- public void EmitAutogeneratedSummary(string prefixSpaces, string extra)
- {
- EmitLine($"{prefixSpaces}/// Autogenerated type. {extra}");
- }
-
- 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($" internal interface I{MangleMethodClass(c, m)} : IMethod");
- EmitLine(" {");
- foreach (AmqpField f in m.m_Fields)
- {
- EmitSpecComment(f.DocumentationComment(" "));
- EmitLine($" {MapDomain(f.Domain)} {MangleClass(f.Name)} {{ get; }}");
- }
- EmitLine(" }");
- }
- }
-
- public bool HasFactoryMethod(AmqpClass c)
- {
- foreach (Type t in m_modelTypes)
- {
- foreach (MethodInfo method in t.GetMethods())
- {
- AmqpContentHeaderFactoryAttribute f = method.Attribute();
- if (f != null && MangleClass(f.m_contentClass) == MangleClass(c.Name))
- {
- return true;
- }
- }
- }
- return false;
- }
-
- public bool IsBoolean(AmqpField f)
- {
- return ResolveDomain(f.Domain) == "bit";
- }
-
- public bool IsReferenceType(AmqpField f)
- {
- return m_primitiveTypeFlagMap[ResolveDomain(f.Domain)];
- }
-
- public bool IsAmqpClass(Type t)
- {
- foreach (AmqpClass c in m_classes)
- {
- if (c.Name == t.Name)
- {
- return true;
- }
- }
- return false;
- }
-
- public void EmitClassProperties(AmqpClass c)
- {
- bool hasCommonApi = HasFactoryMethod(c);
- string propertiesBaseClass = $"RabbitMQ.Client.Impl.{(hasCommonApi ? $"{MangleClass(c.Name)}Properties" : "ContentHeaderBase")}";
- string maybeOverride = hasCommonApi ? "override " : "";
-
- EmitAutogeneratedSummary(" ", $"AMQP specification content header properties for content class \"{c.Name}\"");
- EmitSpecComment(c.DocumentationCommentVariant(" ", "remarks"));
- EmitLine($" internal sealed class {MangleClass(c.Name)}Properties : {propertiesBaseClass}");
- EmitLine(" {");
- foreach (AmqpField f in c.m_Fields)
- {
- EmitLine($" private {MapDomain(f.Domain)} _{MangleMethod(f.Name)};");
- }
- EmitLine("");
- foreach (AmqpField f in c.m_Fields)
- {
- EmitSpecComment(f.DocumentationComment(" ", "@label"));
- EmitLine($" public {maybeOverride}{MapDomain(f.Domain)} {MangleClass(f.Name)}");
- EmitLine(" {");
- EmitLine($" get => _{MangleMethod(f.Name)};");
- EmitLine($" set => _{MangleMethod(f.Name)} = value;");
- EmitLine(" }");
- EmitLine("");
- }
- foreach (AmqpField f in c.m_Fields)
- {
- if (!IsBoolean(f))
- {
- EmitLine($" public {maybeOverride}void Clear{MangleClass(f.Name)}() => _{MangleMethod(f.Name)} = default;");
- EmitLine("");
- }
- }
-
- foreach (AmqpField f in c.m_Fields)
- {
- if (!IsBoolean(f))
- {
- EmitLine($" public {maybeOverride}bool Is{MangleClass(f.Name)}Present() => _{MangleMethod(f.Name)} != default;");
- EmitLine("");
- }
- }
-
- EmitLine($" public {MangleClass(c.Name)}Properties() {{ }}");
- EmitLine($" public override ushort ProtocolClassId => {c.Index};");
- EmitLine($" public override string ProtocolClassName => \"{c.Name}\";");
- EmitLine("");
- EmitLine(" internal override void ReadPropertiesFrom(ref Client.Impl.ContentHeaderPropertyReader reader)");
- EmitLine(" {");
- foreach (AmqpField f in c.m_Fields)
- {
- if (IsBoolean(f))
- {
- EmitLine($" var {MangleMethod(f.Name)} = reader.ReadBit();");
- }
- else
- {
- EmitLine($" var {MangleMethod(f.Name)}_present = reader.ReadPresence();");
- }
- }
- EmitLine(" reader.FinishPresence();");
- foreach (AmqpField f in c.m_Fields)
- {
- if (!IsBoolean(f))
- {
- EmitLine($" if ({MangleMethod(f.Name)}_present) {{ _{MangleMethod(f.Name)} = reader.Read{MangleClass(ResolveDomain(f.Domain))}(); }}");
- }
- }
- EmitLine(" }");
- EmitLine("");
- EmitLine(" internal override void WritePropertiesTo(ref Client.Impl.ContentHeaderPropertyWriter writer)");
- EmitLine(" {");
- foreach (AmqpField f in c.m_Fields)
- {
- if (IsBoolean(f))
- {
- EmitLine($" writer.WriteBit(_{MangleMethod(f.Name)});");
- }
- else
- {
- EmitLine($" writer.WritePresence(Is{MangleClass(f.Name)}Present());");
- }
- }
- EmitLine(" writer.FinishPresence();");
- foreach (AmqpField f in c.m_Fields)
- {
- if (!IsBoolean(f))
- {
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ writer.Write{MangleClass(ResolveDomain(f.Domain))}(_{MangleMethod(f.Name)}); }}");
- }
- }
- EmitLine(" }");
- EmitLine("");
- EmitLine(" public override int GetRequiredPayloadBufferSize()");
- EmitLine(" {");
- EmitLine($" int bufferSize = {Math.Max((int)Math.Ceiling(c.m_Fields.Count / 15.0), 1) * 2}; // number of presence fields ({c.m_Fields.Count}) in 2 bytes blocks");
- foreach (AmqpField f in c.m_Fields)
- {
- switch (MapDomain(f.Domain))
- {
- case "byte":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize++; }} // _{MangleMethod(f.Name)} in bytes");
- break;
- case "string":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize += 1 + Encoding.UTF8.GetByteCount(_{MangleMethod(f.Name)}); }} // _{MangleMethod(f.Name)} in bytes");
- break;
- case "byte[]":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize += 4 + _{MangleMethod(f.Name)}.Length; }} // _{MangleMethod(f.Name)} in bytes");
- break;
- case "ushort":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize += 2; }} // _{MangleMethod(f.Name)} in bytes");
- break;
- case "uint":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize += 4; }} // _{MangleMethod(f.Name)} in bytes");
- break;
- case "ulong":
- case "AmqpTimestamp":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize += 8; }} // _{MangleMethod(f.Name)} in bytes");
- break;
- case "bool":
- // TODO: implement if used, not used anywhere yet
- break;
- case "IDictionary":
- EmitLine($" if (Is{MangleClass(f.Name)}Present()) {{ bufferSize += WireFormatting.GetTableByteCount(_{MangleMethod(f.Name)}); }} // _{MangleMethod(f.Name)} in bytes");
- break;
- default:
- throw new ArgumentOutOfRangeException($"Can't handle size calculations for type = {f.Domain};");
- }
- }
-
- EmitLine(" return bufferSize;");
- EmitLine(" }");
- EmitLine("");
- EmitLine(" public override void AppendPropertyDebugStringTo(StringBuilder sb)");
- EmitLine(" {");
- 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($".Append(_{MangleMethod(f.Name)})");
- }
- else
- {
- Emit($".Append(Is{MangleClass(f.Name)}Present() ? _{MangleMethod(f.Name)}.ToString() : \"_\")");
- }
- remaining--;
- if (remaining > 0)
- {
- EmitLine(".Append(\", \");");
- }
- else
- {
- EmitLine(";");
- }
- }
- }
- EmitLine(" sb.Append(\")\");");
- EmitLine(" }");
- EmitLine(" }");
- }
-
- public void EmitPrivate()
- {
- EmitLine($"namespace {ImplNamespaceBase}");
- EmitLine("{");
- EmitLine(" internal static class ClassConstants");
- EmitLine(" {");
- foreach (AmqpClass c in m_classes)
- {
- EmitLine($" internal const ushort {MangleConstant(c.Name)} = {c.Index};");
- }
- EmitLine(" }");
- EmitLine("");
- EmitLine(" internal enum ClassId");
- EmitLine(" {");
- foreach (AmqpClass c in m_classes)
- {
- EmitLine($" {MangleConstant(c.Name)} = {c.Index},");
- }
- EmitLine(" Invalid = -1,");
- EmitLine(" }");
- EmitLine("");
- foreach (AmqpClass c in m_classes)
- {
- EmitLine($" internal static class {MangleClass(c.Name)}MethodConstants");
- EmitLine(" {");
- foreach (AmqpMethod m in c.m_Methods)
- {
- EmitLine($" internal const ushort {MangleConstant(m.Name)} = {m.Index};");
- }
- EmitLine(" }");
- }
- EmitLine("");
- foreach (AmqpClass c in m_classes)
- {
- EmitClassMethodImplementations(c);
- }
- EmitLine("");
- EmitModelImplementation();
- EmitLine("}");
- }
-
- public void EmitClassMethodImplementations(AmqpClass c)
- {
- foreach (AmqpMethod m in c.m_Methods)
- {
- EmitAutogeneratedSummary(" ", "Private implementation class - do not use directly.");
- EmitLine($" internal sealed class {MangleMethodClass(c, m)} : Client.Impl.MethodBase, I{MangleMethodClass(c, m)}");
- EmitLine(" {");
- foreach (AmqpField f in m.m_Fields)
- {
- EmitLine($" public {MapDomain(f.Domain)} _{MangleMethod(f.Name)};");
- }
- EmitLine("");
- foreach (AmqpField f in m.m_Fields)
- {
- EmitLine($" {MapDomain(f.Domain)} I{MangleMethodClass(c, m)}.{MangleClass(f.Name)} => _{MangleMethod(f.Name)};");
- }
- EmitLine("");
- if (m.m_Fields.Count > 0)
- {
- EmitLine($" public {MangleMethodClass(c, m)}() {{}}");
- }
- EmitLine($" public {MangleMethodClass(c, m)}({string.Join(", ", m.m_Fields.Select(f => $"{MapDomain(f.Domain)} @{MangleClass(f.Name)}"))})");
- EmitLine(" {");
- foreach (AmqpField f in m.m_Fields)
- {
- EmitLine($" _{MangleMethod(f.Name)} = @{MangleClass(f.Name)};");
- }
- EmitLine(" }");
- EmitLine("");
- EmitLine($" public override ushort ProtocolClassId => ClassConstants.{MangleConstant(c.Name)};");
- EmitLine($" public override ushort ProtocolMethodId => {MangleConstant(c.Name)}MethodConstants.{MangleConstant(m.Name)};");
- EmitLine($" public override string ProtocolMethodName => \"{c.Name}.{m.Name}\";");
- EmitLine($" public override bool HasContent => {(m.HasContent ? "true" : "false")};");
- EmitLine("");
- EmitLine(" public override void ReadArgumentsFrom(ref Client.Impl.MethodArgumentReader reader)");
- EmitLine(" {");
- foreach (AmqpField f in m.m_Fields)
- {
- EmitLine($" _{MangleMethod(f.Name)} = reader.Read{MangleClass(ResolveDomain(f.Domain))}();");
- }
- EmitLine(" }");
- EmitLine("");
- EmitLine(" public override void WriteArgumentsTo(ref Client.Impl.MethodArgumentWriter writer)");
- EmitLine(" {");
- var lastWasBitClass = false;
- foreach (AmqpField f in m.m_Fields)
- {
- string mangleClass = MangleClass(ResolveDomain(f.Domain));
- if (mangleClass != "Bit")
- {
- if (lastWasBitClass)
- {
- EmitLine($" writer.EndBits();");
- lastWasBitClass = false;
- }
- }
- else
- {
- lastWasBitClass = true;
- }
-
- EmitLine($" writer.Write{mangleClass}(_{MangleMethod(f.Name)});");
- }
- if (lastWasBitClass)
- {
- EmitLine($" writer.EndBits();");
- }
- EmitLine(" }");
- EmitLine("");
- EmitLine(" public override int GetRequiredBufferSize()");
- EmitLine(" {");
-
- int bitCount = 0;
- int bytesSize = 0;
- var commentBuilder = new StringBuilder(" // bytes for ");
- foreach (AmqpField f in m.m_Fields)
- {
- switch (MapDomain(f.Domain))
- {
- case "byte":
- bytesSize++;
- commentBuilder.Append('_').Append(MangleMethod(f.Name)).Append(", ");
- break;
- case "string":
- bytesSize++;
- commentBuilder.Append("length of _").Append(MangleMethod(f.Name)).Append(", ");
- break;
- case "byte[]":
- bytesSize += 4;
- commentBuilder.Append("length of _").Append(MangleMethod(f.Name)).Append(", ");
- break;
- case "ushort":
- bytesSize += 2;
- commentBuilder.Append('_').Append(MangleMethod(f.Name)).Append(", ");
- break;
- case "uint":
- bytesSize += 4;
- commentBuilder.Append('_').Append(MangleMethod(f.Name)).Append(", ");
- break;
- case "ulong":
- case "AmqpTimestamp":
- bytesSize += 8;
- commentBuilder.Append('_').Append(MangleMethod(f.Name)).Append(", ");
- break;
- case "bool":
- if (bitCount == 0)
- {
- commentBuilder.Append("bit fields, ");
- }
- bitCount++;
- break;
- case "IDictionary":
- break;
- default:
- throw new ArgumentOutOfRangeException($"Can't handle size calculations for type = {f.Domain};");
- }
- }
-
- // 13 = " // bytes for "
- if (commentBuilder.Length > 14)
- {
- // cut of last ", "
- commentBuilder.Length -= 2;
- }
- else
- {
- commentBuilder.Clear();
- }
- bytesSize += (int)Math.Ceiling(bitCount / 8.0);
- EmitLine($" int bufferSize = {bytesSize};{commentBuilder}");
- foreach (AmqpField f in m.m_Fields)
- {
- switch (MapDomain(f.Domain))
- {
- case "byte":
- case "ushort":
- case "uint":
- case "ulong":
- case "AmqpTimestamp":
- case "bool":
- // size already calculated
- break;
- case "string":
- EmitLine($" bufferSize += Encoding.UTF8.GetByteCount(_{MangleMethod(f.Name)}); // _{MangleMethod(f.Name)} in bytes");
- break;
- case "byte[]":
- EmitLine($" bufferSize += _{MangleMethod(f.Name)}.Length; // _{MangleMethod(f.Name)} in bytes");
- break;
- case "IDictionary":
- EmitLine($" bufferSize += WireFormatting.GetTableByteCount(_{MangleMethod(f.Name)}); // _{MangleMethod(f.Name)} in bytes");
- break;
- default:
- throw new ArgumentOutOfRangeException($"Can't handle size calculations for type = {f.Domain};");
- }
- }
-
- EmitLine(" return bufferSize;");
- EmitLine(" }");
- EmitLine("");
- EmitLine(" public override void AppendArgumentDebugStringTo(StringBuilder sb)");
- EmitLine(" {");
- EmitLine(" sb.Append('(');");
- {
- int remaining = m.m_Fields.Count;
- foreach (AmqpField f in m.m_Fields)
- {
- Emit($" sb.Append(_{MangleMethod(f.Name)})");
- remaining--;
- if (remaining > 0)
- {
- EmitLine(".Append(',');");
- }
- else
- {
- EmitLine(";");
- }
- }
- }
- EmitLine(" sb.Append(')');");
- EmitLine(" }");
- EmitLine(" }");
- }
- }
-
- public void EmitMethodArgumentReader()
- {
- EmitLine(" internal override Client.Impl.MethodBase DecodeMethodFrom(ReadOnlySpan span)");
- EmitLine(" {");
- EmitLine(" ushort classId = Util.NetworkOrderDeserializer.ReadUInt16(span);");
- EmitLine(" ushort methodId = Util.NetworkOrderDeserializer.ReadUInt16(span.Slice(2));");
- EmitLine(" Client.Impl.MethodBase result = DecodeMethodFrom(classId, methodId);");
- EmitLine(" if(result != null)");
- EmitLine(" {");
- EmitLine(" Client.Impl.MethodArgumentReader reader = new Client.Impl.MethodArgumentReader(span.Slice(4));");
- EmitLine(" result.ReadArgumentsFrom(ref reader);");
- EmitLine(" return result;");
- EmitLine(" }");
- EmitLine("");
- EmitLine(" throw new Client.Exceptions.UnknownClassOrMethodException(classId, methodId);");
- EmitLine(" }");
- EmitLine("");
- EmitLine(" internal Client.Impl.MethodBase DecodeMethodFrom(ushort classId, ushort methodId)");
- EmitLine(" {");
- EmitLine(" switch ((classId << 16) | methodId)");
- EmitLine(" {");
- foreach (AmqpClass c in m_classes)
- {
- foreach (AmqpMethod m in c.m_Methods)
- {
- EmitLine($" case (ClassConstants.{MangleConstant(c.Name)} << 16) | {MangleConstant(c.Name)}MethodConstants.{MangleConstant(m.Name)}: return new Impl.{MangleMethodClass(c, m)}();");
- }
- }
- EmitLine(" default: return null;");
- EmitLine(" }");
- EmitLine(" }");
- EmitLine("");
- }
-
- public void EmitContentHeaderReader()
- {
- EmitLine(" internal override Client.Impl.ContentHeaderBase DecodeContentHeaderFrom(ushort classId)");
- EmitLine(" {");
- EmitLine(" switch (classId)");
- EmitLine(" {");
- foreach (AmqpClass c in m_classes)
- {
- if (c.NeedsProperties)
- {
- EmitLine($" case {c.Index}: return new {MangleClass(c.Name)}Properties();");
- }
- }
- EmitLine(" default: throw new Client.Exceptions.UnknownClassOrMethodException(classId, 0);");
- EmitLine(" }");
- EmitLine(" }");
- }
-
- public Attribute Attribute(MemberInfo mi, Type t)
- {
- return Attribute(mi.GetCustomAttributes(t, false), t);
- }
-
- public Attribute Attribute(ParameterInfo pi, Type t)
- {
- return Attribute(pi.GetCustomAttributes(t, false), t);
- }
-
- public Attribute Attribute(ICustomAttributeProvider p, Type t)
- {
- return Attribute(p.GetCustomAttributes(t, false), t);
- }
-
- public Attribute Attribute(IEnumerable