/// <summary> /// Parses the messages section of a protocol definition /// </summary> /// <param name="jmessage">messages JSON object</param> /// <param name="names">list of parsed names</param> /// <param name="encspace">enclosing namespace</param> /// <returns></returns> internal static Message Parse(JProperty jmessage, SchemaNames names, string encspace) { string name = jmessage.Name; string doc = JsonHelper.GetOptionalString(jmessage.Value, "doc"); bool? oneway = JsonHelper.GetOptionalBoolean(jmessage.Value, "one-way"); PropertyMap props = Schema.GetProperties(jmessage.Value); RecordSchema schema = RecordSchema.NewInstance(Schema.Type.Record, jmessage.Value as JObject, props, names, encspace); JToken jresponse = jmessage.Value["response"]; var response = Schema.ParseJson(jresponse, names, encspace); JToken jerrors = jmessage.Value["errors"]; UnionSchema uerrorSchema = null; if (null != jerrors) { Schema errorSchema = Schema.ParseJson(jerrors, names, encspace); if (!(errorSchema is UnionSchema)) throw new AvroException(""); uerrorSchema = errorSchema as UnionSchema; } return new Message(name, doc, schema, response, uerrorSchema, oneway); }
/// <summary> /// Writes the Field class in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace for the field</param> protected internal void writeJson(JsonTextWriter writer, SchemaNames names, string encspace) { writer.WriteStartObject(); JsonHelper.writeIfNotNullOrEmpty(writer, "name", this.Name); JsonHelper.writeIfNotNullOrEmpty(writer, "doc", this.Documentation); if (null != this.DefaultValue) { writer.WritePropertyName("default"); this.DefaultValue.WriteTo(writer, null); } if (null != this.Schema) { writer.WritePropertyName("type"); Schema.WriteJson(writer, names, encspace); } if (null != this.Props) { this.Props.WriteJson(writer); } if (null != aliases) { writer.WritePropertyName("aliases"); writer.WriteStartArray(); foreach (string name in aliases) { writer.WriteValue(name); } writer.WriteEndArray(); } writer.WriteEndObject(); }
/// <summary> /// Generates code for the protocol objects. /// </summary> /// <exception cref="CodeGenException">Names in protocol should only be of type NamedSchema, type found {sn.Value.Tag}</exception> protected virtual void ProcessProtocols() { foreach (Protocol protocol in Protocols) { SchemaNames names = GenerateNames(protocol); foreach (KeyValuePair <SchemaName, NamedSchema> sn in names) { switch (sn.Value.Tag) { case Schema.Type.Enumeration: processEnum(sn.Value); break; case Schema.Type.Fixed: processFixed(sn.Value); break; case Schema.Type.Record: processRecord(sn.Value); break; case Schema.Type.Error: processRecord(sn.Value); break; default: throw new CodeGenException($"Names in protocol should only be of type NamedSchema, type found {sn.Value.Tag}"); } } processInterface(protocol); } }
static void GenSchema(List <string> infiles, string outdir, IEnumerable <KeyValuePair <string, string> > namespaceMapping) { try { var sn = new SchemaNames(); CodeGen codegen = new CodeGen(); foreach (var infile in infiles) { string text = System.IO.File.ReadAllText(infile); Schema schema = Schema.Parse(text, sn); codegen.AddSchema(schema); } foreach (var entry in namespaceMapping) { codegen.NamespaceMapping[entry.Key] = entry.Value; } codegen.GenerateCode(); codegen.WriteTypes(outdir); } catch (Exception ex) { Console.WriteLine("Exception occurred. " + ex.Message); } }
/// <summary> /// Static function to return new instance of the fixed schema class /// </summary> /// <param name="jtok">JSON object for the fixed schema</param> /// <param name="names">list of named schema already parsed in</param> /// <param name="encspace">enclosing namespace of the fixed schema</param> /// <returns></returns> internal static FixedSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { SchemaName name = NamedSchema.GetName(jtok, encspace); var aliases = NamedSchema.GetAliases(jtok, name.Space, name.EncSpace); return new FixedSchema(name, aliases, JsonHelper.GetRequiredInteger(jtok, "size"), props, names); }
/// <summary> /// Constructor /// </summary> /// <param name="name">name of the fixed schema</param> /// <param name="aliases">list of aliases for the name</param> /// <param name="size">fixed size</param> /// <param name="names">list of named schema already parsed in</param> private FixedSchema(SchemaName name, IList<SchemaName> aliases, int size, PropertyMap props, SchemaNames names) : base(Type.Fixed, name, aliases, props, names) { if (null == name.Name) throw new SchemaParseException("name cannot be null for fixed schema."); if (size <= 0) throw new ArgumentOutOfRangeException("size", "size must be greater than zero."); this.Size = size; }
/// <summary> /// Static function to return new instance of map schema /// </summary> /// <param name="jtok">JSON object for the map schema</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the map schema</param> /// <returns></returns> internal static MapSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { JToken jvalue = jtok["values"]; if (null == jvalue) throw new AvroTypeException("Map does not have 'values'"); return new MapSchema(Schema.ParseJson(jvalue, names, encspace), props); }
/// <summary> /// Creates a new field for the record /// </summary> /// <param name="jfield">JSON object for the field</param> /// <param name="pos">position number of the field</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the records schema</param> /// <returns>new Field object</returns> private static Field createField(JToken jfield, int pos, SchemaNames names, string encspace) { var name = JsonHelper.GetRequiredString(jfield, "name"); var doc = JsonHelper.GetOptionalString(jfield, "doc"); var jorder = JsonHelper.GetOptionalString(jfield, "order"); Field.SortOrder sortorder = Field.SortOrder.ignore; if (null != jorder) { sortorder = (Field.SortOrder)Enum.Parse(typeof(Field.SortOrder), jorder); } var aliases = Field.GetAliases(jfield); var props = Schema.GetProperties(jfield); var defaultValue = jfield["default"]; JToken jtype = jfield["type"]; if (null == jtype) { throw new SchemaParseException($"'type' was not found for field: name at '{jfield.Path}'"); } var schema = Schema.ParseJson(jtype, names, encspace); return(new Field(schema, name, aliases, pos, doc, defaultValue, sortorder, props)); }
/// <summary> /// Generate list of named schemas from given schema. /// </summary> /// <param name="schema">schema to process.</param> /// <returns> /// List of named schemas. /// </returns> protected virtual SchemaNames GenerateNames(Schema schema) { var names = new SchemaNames(); addName(schema, names); return(names); }
/// <summary> /// Static class to return a new instance of ArraySchema /// </summary> /// <param name="jtok">JSON object for the array schema</param> /// <param name="names">list of named schemas already parsed</param> /// <param name="encspace">enclosing namespace for the array schema</param> /// <returns></returns> internal static ArraySchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { JToken jitem = jtok["items"]; if (null == jitem) throw new AvroTypeException("Array does not have 'items'"); return new ArraySchema(Schema.ParseJson(jitem, names, encspace), props); }
/// <summary> /// Static function to return new instance of the fixed schema class /// </summary> /// <param name="jtok">JSON object for the fixed schema</param> /// <param name="names">list of named schema already parsed in</param> /// <param name="encspace">enclosing namespace of the fixed schema</param> /// <returns></returns> internal static FixedSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { SchemaName name = NamedSchema.GetName(jtok, encspace); var aliases = NamedSchema.GetAliases(jtok, name.Space, name.EncSpace); return(new FixedSchema(name, aliases, JsonHelper.GetRequiredInteger(jtok, "size"), props, names)); }
/// <summary> /// Static function to return a new instance of the named schema /// </summary> /// <param name="jo">JSON object of the named schema</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the named schema</param> /// <returns></returns> internal static NamedSchema NewInstance(JObject jo, PropertyMap props, SchemaNames names, string encspace) { string type = JsonHelper.GetRequiredString(jo, "type"); switch (type) { case "fixed": return(FixedSchema.NewInstance(jo, props, names, encspace)); case "enum": return(EnumSchema.NewInstance(jo, props, names, encspace)); case "record": return(RecordSchema.NewInstance(Type.Record, jo, props, names, encspace)); case "error": return(RecordSchema.NewInstance(Type.Error, jo, props, names, encspace)); default: NamedSchema result; if (names.TryGetValue(type, null, encspace, out result)) { return(result); } return(null); } }
/// <summary> /// Writes the messages section of a protocol definition /// </summary> /// <param name="writer">writer</param> /// <param name="names">list of names written</param> /// <param name="encspace">enclosing namespace</param> internal void writeJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { writer.WriteStartObject(); JsonHelper.writeIfNotNullOrEmpty(writer, "doc", this.Doc); if (null != this.Request) { this.Request.WriteJsonFields(writer, names, null); } if (null != this.Response) { writer.WritePropertyName("response"); Response.WriteJson(writer, names, encspace); } if (null != this.Error) { writer.WritePropertyName("errors"); this.Error.WriteJson(writer, names, encspace); } if (null != Oneway) { writer.WritePropertyName("one-way"); writer.WriteValue(Oneway); } writer.WriteEndObject(); }
/// <summary> /// Parses the messages section of a protocol definition /// </summary> /// <param name="jmessage">messages JSON object</param> /// <param name="names">list of parsed names</param> /// <param name="encspace">enclosing namespace</param> /// <returns></returns> internal static Message Parse(JProperty jmessage, SchemaNames names, string encspace) { string name = jmessage.Name; string doc = JsonHelper.GetOptionalString(jmessage.Value, "doc"); bool? oneway = JsonHelper.GetOptionalBoolean(jmessage.Value, "one-way"); PropertyMap props = Schema.GetProperties(jmessage.Value); RecordSchema schema = RecordSchema.NewInstance(Schema.Type.Record, jmessage.Value as JObject, props, names, encspace); JToken jresponse = jmessage.Value["response"]; var response = Schema.ParseJson(jresponse, names, encspace); JToken jerrors = jmessage.Value["errors"]; UnionSchema uerrorSchema = null; if (null != jerrors) { Schema errorSchema = Schema.ParseJson(jerrors, names, encspace); if (!(errorSchema is UnionSchema)) { throw new AvroException(""); } uerrorSchema = errorSchema as UnionSchema; } return(new Message(name, doc, schema, response, uerrorSchema, oneway)); }
/// <summary> /// Parses the given JSON object to create a Protocol object /// </summary> /// <param name="jtok">JSON object</param> /// <returns>Protocol object</returns> private static Protocol Parse(JToken jtok) { string name = JsonHelper.GetRequiredString(jtok, "protocol"); string space = JsonHelper.GetOptionalString(jtok, "namespace"); string doc = JsonHelper.GetOptionalString(jtok, "doc"); var names = new SchemaNames(); JToken jtypes = jtok["types"]; var types = new List <Schema>(); if (jtypes is JArray) { foreach (JToken jtype in jtypes) { var schema = Schema.ParseJson(jtype, names, space); types.Add(schema); } } var messages = new Dictionary <string, Message>(); JToken jmessages = jtok["messages"]; if (null != jmessages) { foreach (JProperty jmessage in jmessages) { var message = Message.Parse(jmessage, names, space); messages.Add(message.Name, message); } } return(new Protocol(name, space, doc, types, messages)); }
/// <summary> /// Writes Protocol in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> internal void WriteJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names) { writer.WriteStartObject(); JsonHelper.writeIfNotNullOrEmpty(writer, "protocol", this.Name); JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.Namespace); JsonHelper.writeIfNotNullOrEmpty(writer, "doc", this.Doc); writer.WritePropertyName("types"); writer.WriteStartArray(); foreach (Schema type in this.Types) { type.WriteJson(writer, names, this.Namespace); } writer.WriteEndArray(); writer.WritePropertyName("messages"); writer.WriteStartObject(); foreach (KeyValuePair <string, Message> message in this.Messages) { writer.WritePropertyName(message.Key); message.Value.writeJson(writer, names, this.Namespace); } writer.WriteEndObject(); writer.WriteEndObject(); }
/// <summary> /// Static function to return new instance of EnumSchema /// </summary> /// <param name="jtok">JSON object for enum schema</param> /// <param name="names">list of named schema already parsed in</param> /// <param name="encspace">enclosing namespace for the enum schema</param> /// <returns>new instance of enum schema</returns> internal static EnumSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { SchemaName name = NamedSchema.GetName(jtok, encspace); var aliases = NamedSchema.GetAliases(jtok, name.Space, name.EncSpace); JArray jsymbols = jtok["symbols"] as JArray; if (null == jsymbols) { throw new SchemaParseException("Enum has no symbols: " + name); } List <string> symbols = new List <string>(); IDictionary <string, int> symbolMap = new Dictionary <string, int>(); int i = 0; foreach (JValue jsymbol in jsymbols) { string s = (string)jsymbol.Value; if (symbolMap.ContainsKey(s)) { throw new SchemaParseException("Duplicate symbol: " + s); } symbolMap[s] = i++; symbols.Add(s); } return(new EnumSchema(name, aliases, symbols, symbolMap, props, names, JsonHelper.GetOptionalString(jtok, "doc"))); }
/// <summary> /// Static function to return instance of the union schema /// </summary> /// <param name="jarr">JSON object for the union schema</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the schema</param> /// <returns>new UnionSchema object</returns> internal static UnionSchema NewInstance(JArray jarr, PropertyMap props, SchemaNames names, string encspace) { List <Schema> schemas = new List <Schema>(); IDictionary <string, string> uniqueSchemas = new Dictionary <string, string>(); foreach (JToken jvalue in jarr) { Schema unionType = Schema.ParseJson(jvalue, names, encspace); if (null == unionType) { throw new SchemaParseException("Invalid JSON in union" + jvalue.ToString()); } string name = unionType.Fullname; if (uniqueSchemas.ContainsKey(name)) { throw new SchemaParseException("Duplicate type in union: " + name); } uniqueSchemas.Add(name, name); schemas.Add(unionType); } return(new UnionSchema(schemas, props)); }
/// <summary> /// /// </summary> /// <param name="json"></param> /// <param name="schemaNames">schemas already read</param> /// <returns></returns> public static Schema Parse(string json, SchemaNames schemaNames) { if (string.IsNullOrEmpty(json)) { throw new ArgumentNullException(nameof(json), "json cannot be null."); } return(Parse(json.Trim(), schemaNames, null)); }
/// <summary> /// Constructor for enum schema /// </summary> /// <param name="name">name of enum</param> /// <param name="aliases">list of aliases for the name</param> /// <param name="symbols">list of enum symbols</param> /// <param name="symbolMap">map of enum symbols and value</param> /// <param name="names">list of named schema already read</param> private EnumSchema(SchemaName name, IList<SchemaName> aliases, List<string> symbols, IDictionary<String, int> symbolMap, PropertyMap props, SchemaNames names) : base(Type.Enumeration, name, aliases, props, names) { if (null == name.Name) throw new SchemaParseException("name cannot be null for enum schema."); this.Symbols = symbols; this.symbolMap = symbolMap; }
/// <summary> /// Constructor for named schema class /// </summary> /// <param name="type">schema type</param> /// <param name="name">name</param> /// <param name="names">list of named schemas already read</param> protected NamedSchema(Type type, SchemaName name, IList<SchemaName> aliases, PropertyMap props, SchemaNames names) : base(type, props) { this.SchemaName = name; this.aliases = aliases; if (null != name.Name) // Added this check for anonymous records inside Message if (!names.Add(name, this)) throw new AvroException("Duplicate schema name " + name.Fullname); }
/// <summary> /// Writes schema object in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the schema</param> protected internal virtual void WriteJson(JsonTextWriter writer, SchemaNames names, string encspace) { writeStartObject(writer); WriteJsonFields(writer, names, encspace); if (null != this.Props) { Props.WriteJson(writer); } writer.WriteEndObject(); }
/// <summary> /// Generate list of named schemas from given protocol /// </summary> /// <param name="protocol">protocol to process</param> /// <returns></returns> protected virtual SchemaNames generateNames(Protocol protocol) { var names = new SchemaNames(); foreach (Schema schema in protocol.Types) { addName(schema, names); } return(names); }
/// <summary> /// Static class to return a new instance of ArraySchema /// </summary> /// <param name="jtok">JSON object for the array schema</param> /// <param name="names">list of named schemas already parsed</param> /// <param name="encspace">enclosing namespace for the array schema</param> /// <returns></returns> internal static ArraySchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { JToken jitem = jtok["items"]; if (null == jitem) { throw new AvroTypeException("Array does not have 'items'"); } return(new ArraySchema(Schema.ParseJson(jitem, names, encspace), props)); }
/// <summary> /// Static function to return new instance of map schema /// </summary> /// <param name="jtok">JSON object for the map schema</param> /// <param name="props">dictionary that provides access to custom properties</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the map schema</param> /// <returns></returns> internal static MapSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { JToken jvalue = jtok["values"]; if (null == jvalue) { throw new AvroTypeException("Map does not have 'values'"); } return(new MapSchema(Schema.ParseJson(jvalue, names, encspace), props)); }
/// <summary> /// Constructor for enum schema /// </summary> /// <param name="name">name of enum</param> /// <param name="aliases">list of aliases for the name</param> /// <param name="symbols">list of enum symbols</param> /// <param name="symbolMap">map of enum symbols and value</param> /// <param name="names">list of named schema already read</param> private EnumSchema(SchemaName name, IList <SchemaName> aliases, List <string> symbols, IDictionary <String, int> symbolMap, PropertyMap props, SchemaNames names) : base(Type.Enumeration, name, aliases, props, names) { if (null == name.Name) { throw new SchemaParseException("name cannot be null for enum schema."); } this.Symbols = symbols; this.symbolMap = symbolMap; }
internal static LogicalSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { JToken jtype = jtok["type"]; if (null == jtype) { throw new AvroTypeException("Logical Type does not have 'type'"); } return(new LogicalSchema(Schema.ParseJson(jtype, names, encspace), JsonHelper.GetRequiredString(jtok, "logicalType"), props)); }
/// <summary> /// Writes enum schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schema already written</param> /// <param name="encspace">enclosing namespace of the enum schema</param> protected internal override void WriteJsonFields(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { base.WriteJsonFields(writer, names, encspace); writer.WritePropertyName("symbols"); writer.WriteStartArray(); foreach (string s in this.Symbols) { writer.WriteValue(s); } writer.WriteEndArray(); }
/// <summary> /// Parses a given JSON string to create a new schema object /// </summary> /// <param name="json">JSON string</param> /// <param name="names">list of named schemas already read</param> /// <returns>new Schema object</returns> public static Schema Parse(string json, SchemaNames names) { json = json?.Trim(); if (string.IsNullOrEmpty(json)) { throw new ArgumentNullException(nameof(json), $"{nameof(json)} cannot be null"); } if (names == null) { throw new ArgumentNullException(nameof(names), $"{nameof(names)} cannot be null"); } return(Parse(json, names, null)); // standalone schema, so no enclosing namespace }
/// <summary> /// Constructor for the record schema /// </summary> /// <param name="type">type of record schema, either record or error</param> /// <param name="name">name of the record schema</param> /// <param name="aliases">list of aliases for the record name</param> /// <param name="props">custom properties on this schema</param> /// <param name="fields">list of fields for the record</param> /// <param name="request">true if this is an anonymous record with 'request' instead of 'fields'</param> /// <param name="fieldMap">map of field names and field objects</param> /// <param name="fieldAliasMap">map of field aliases and field objects</param> /// <param name="names">list of named schema already read</param> /// <param name="doc">documentation for this named schema</param> private RecordSchema(Type type, SchemaName name, IList <SchemaName> aliases, PropertyMap props, List <Field> fields, bool request, IDictionary <string, Field> fieldMap, IDictionary <string, Field> fieldAliasMap, SchemaNames names, string doc) : base(type, name, aliases, props, names, doc) { if (!request && null == name.Name) { throw new SchemaParseException("name cannot be null for record schema."); } this.Fields = fields; this.request = request; this.fieldLookup = fieldMap; this.fieldAliasLookup = fieldAliasMap; }
/// <summary> /// Static class to return new instance of schema object /// </summary> /// <param name="jtok">JSON object</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the schema</param> /// <returns>new Schema object</returns> internal static Schema ParseJson(JToken jtok, SchemaNames names, string encspace) { if (null == jtok) throw new ArgumentNullException("j", "j cannot be null."); if (jtok.Type == JTokenType.String) // primitive schema with no 'type' property or primitive or named type of a record field { string value = (string)jtok; PrimitiveSchema ps = PrimitiveSchema.NewInstance(value); if (null != ps) return ps; NamedSchema schema = null; if (names.TryGetValue(value, null, encspace, out schema)) return schema; throw new SchemaParseException("Undefined name: " + value); } if (jtok is JArray) // union schema with no 'type' property or union type for a record field return UnionSchema.NewInstance(jtok as JArray, null, names, encspace); if (jtok is JObject) // JSON object with open/close parenthesis, it must have a 'type' property { JObject jo = jtok as JObject; JToken jtype = jo["type"]; if (null == jtype) throw new SchemaParseException("Property type is required"); var props = Schema.GetProperties(jtok); if (jtype.Type == JTokenType.String) { string type = (string)jtype; if (type.Equals("array")) return ArraySchema.NewInstance(jtok, props, names, encspace); if (type.Equals("map")) return MapSchema.NewInstance(jtok, props, names, encspace); Schema schema = PrimitiveSchema.NewInstance((string)type, props); if (null != schema) return schema; return NamedSchema.NewInstance(jo, props, names, encspace); } else if (jtype.Type == JTokenType.Array) return UnionSchema.NewInstance(jtype as JArray, props, names, encspace); } throw new AvroTypeException("Invalid JSON for schema: " + jtok); }
/// <summary> /// Writes the schema name in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the schema</param> internal void WriteJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { if (null != this.Name) // write only if not anonymous { JsonHelper.writeIfNotNullOrEmpty(writer, "name", this.Name); if (!String.IsNullOrEmpty(this.Space)) { JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.Space); } else if (!String.IsNullOrEmpty(this.EncSpace)) // need to put enclosing name space for code generated classes { JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.EncSpace); } } }
/// <summary> /// Static function to return new instance of the fixed schema class /// </summary> /// <param name="jtok">JSON object for the fixed schema</param> /// <param name="props">dictionary that provides access to custom properties</param> /// <param name="names">list of named schema already parsed in</param> /// <param name="encspace">enclosing namespace of the fixed schema</param> /// <returns></returns> internal static FixedSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { SchemaName name = NamedSchema.GetName(jtok, encspace); var aliases = NamedSchema.GetAliases(jtok, name.Space, name.EncSpace); try { return(new FixedSchema(name, aliases, JsonHelper.GetRequiredInteger(jtok, "size"), props, names, JsonHelper.GetOptionalString(jtok, "doc"))); } catch (Exception e) { throw new SchemaParseException($"{e.Message} at '{jtok.Path}'", e); } }
/// <summary> /// Generate list of named schemas from given protocol. /// </summary> /// <param name="protocol">protocol to process.</param> /// <returns> /// List of named schemas. /// </returns> /// <exception cref="ArgumentNullException">protocol - Protocol can not be null.</exception> protected virtual SchemaNames GenerateNames(Protocol protocol) { if (protocol == null) { throw new ArgumentNullException(nameof(protocol), "Protocol can not be null"); } var names = new SchemaNames(); foreach (Schema schema in protocol.Types) { addName(schema, names); } return(names); }
/// <summary> /// Static function to return new instance of map schema /// </summary> /// <param name="jtok">JSON object for the map schema</param> /// <param name="props">dictionary that provides access to custom properties</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the map schema</param> /// <returns></returns> internal static MapSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { JToken jvalue = jtok["values"]; if (null == jvalue) { throw new AvroTypeException($"Map does not have 'values' at '{jtok.Path}'"); } try { return(new MapSchema(ParseJson(jvalue, names, encspace), props)); } catch (Exception e) { throw new SchemaParseException($"Error creating MapSchema at '{jtok.Path}'", e); } }
/// <summary> /// Constructor for enum schema /// </summary> /// <param name="name">name of enum</param> /// <param name="aliases">list of aliases for the name</param> /// <param name="symbols">list of enum symbols</param> /// <param name="symbolMap">map of enum symbols and value</param> /// <param name="props">custom properties on this schema</param> /// <param name="names">list of named schema already read</param> /// <param name="doc">documentation for this named schema</param> /// <param name="defaultSymbol">default symbol</param> private EnumSchema(SchemaName name, IList <SchemaName> aliases, List <string> symbols, IDictionary <String, int> symbolMap, PropertyMap props, SchemaNames names, string doc, string defaultSymbol) : base(Type.Enumeration, name, aliases, props, names, doc) { if (null == name.Name) { throw new SchemaParseException("name cannot be null for enum schema."); } this.Symbols = symbols; this.symbolMap = symbolMap; if (null != defaultSymbol && !symbolMap.ContainsKey(defaultSymbol)) { throw new SchemaParseException($"Default symbol: {defaultSymbol} not found in symbols"); } Default = defaultSymbol; }
/// <summary> /// Writes primitive schema in JSON format /// </summary> /// <param name="w"></param> /// <param name="names"></param> /// <param name="encspace"></param> protected internal override void WriteJson(JsonTextWriter w, SchemaNames names, string encspace) { if (this.Props?.Any() == true) { w.WriteStartObject(); w.WritePropertyName("type"); w.WriteValue(Name); foreach (var prop in Props) { w.WritePropertyName(prop.Key); w.WriteRawValue(prop.Value); } w.WriteEndObject(); } else { w.WriteValue(Name); } }
/// <summary> /// Static function to return instance of the union schema /// </summary> /// <param name="jarr">JSON object for the union schema</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the schema</param> /// <returns>new UnionSchema object</returns> internal static UnionSchema NewInstance(JArray jarr, PropertyMap props, SchemaNames names, string encspace) { List<Schema> schemas = new List<Schema>(); IDictionary<string, string> uniqueSchemas = new Dictionary<string, string>(); foreach (JToken jvalue in jarr) { Schema unionType = Schema.ParseJson(jvalue, names, encspace); if (null == unionType) throw new SchemaParseException("Invalid JSON in union" + jvalue.ToString()); string name = unionType.Name; if (uniqueSchemas.ContainsKey(name)) throw new SchemaParseException("Duplicate type in union: " + name); uniqueSchemas.Add(name, name); schemas.Add(unionType); } return new UnionSchema(schemas, props); }
/// <summary> /// Parses a JSON string to create a new schema object /// </summary> /// <param name="json">JSON string</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the schema</param> /// <returns>new Schema object</returns> internal static Schema Parse(string json, SchemaNames names, string encspace) { Schema sc = PrimitiveSchema.NewInstance(json); if (null != sc) { return(sc); } try { bool IsArray = json.StartsWith("[") && json.EndsWith("]"); JContainer j = IsArray ? (JContainer)JArray.Parse(json) : (JContainer)JObject.Parse(json); return(ParseJson(j, names, encspace)); } catch (Newtonsoft.Json.JsonSerializationException ex) { throw new SchemaParseException("Could not parse. " + ex.Message + Environment.NewLine + json); } }
/// <summary> /// Writes schema object in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the schema</param> protected internal virtual void WriteJson(JsonTextWriter writer, SchemaNames names, string encspace) { writeStartObject(writer); WriteJsonFields(writer, names, encspace); if (null != this.Props) Props.WriteJson(writer); writer.WriteEndObject(); }
/// <summary> /// Writes map schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the map schema</param> protected internal override void WriteJsonFields(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { writer.WritePropertyName("values"); ValueSchema.WriteJson(writer, names, encspace); }
/// <summary> /// Parses the given JSON object to create a Protocol object /// </summary> /// <param name="jtok">JSON object</param> /// <returns>Protocol object</returns> private static Protocol Parse(JToken jtok) { string name = JsonHelper.GetRequiredString(jtok, "protocol"); string space = JsonHelper.GetOptionalString(jtok, "namespace"); string doc = JsonHelper.GetOptionalString(jtok, "doc"); var names = new SchemaNames(); JToken jtypes = jtok["types"]; var types = new List<Schema>(); if (jtypes is JArray) { foreach (JToken jtype in jtypes) { var schema = Schema.ParseJson(jtype, names, space); types.Add(schema); } } var messages = new Dictionary<string,Message>(); JToken jmessages = jtok["messages"]; if (null != jmessages) { foreach (JProperty jmessage in jmessages) { var message = Message.Parse(jmessage, names, space); messages.Add(message.Name, message); } } return new Protocol(name, space, doc, types, messages); }
/// <summary> /// Writes the fixed schema class in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schema already written</param> /// <param name="encspace">enclosing namespace for the fixed schema</param> protected internal override void WriteJsonFields(Arch.CMessaging.Client.Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { base.WriteJsonFields(writer, names, encspace); writer.WritePropertyName("size"); writer.WriteValue(this.Size); }
/// <summary> /// Writes Protocol in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> internal void WriteJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names) { writer.WriteStartObject(); JsonHelper.writeIfNotNullOrEmpty(writer, "protocol", this.Name); JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.Namespace); JsonHelper.writeIfNotNullOrEmpty(writer, "doc", this.Doc); writer.WritePropertyName("types"); writer.WriteStartArray(); foreach (Schema type in this.Types) type.WriteJson(writer, names, this.Namespace); writer.WriteEndArray(); writer.WritePropertyName("messages"); writer.WriteStartObject(); foreach (KeyValuePair<string,Message> message in this.Messages) { writer.WritePropertyName(message.Key); message.Value.writeJson(writer, names, this.Namespace); } writer.WriteEndObject(); writer.WriteEndObject(); }
/// <summary> /// Writes the array schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace</param> protected internal override void WriteJsonFields(Arch.CMessaging.Client.Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { writer.WritePropertyName("items"); ItemSchema.WriteJson(writer, names, encspace); }
/// <summary> /// Writes the messages section of a protocol definition /// </summary> /// <param name="writer">writer</param> /// <param name="names">list of names written</param> /// <param name="encspace">enclosing namespace</param> internal void writeJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { writer.WriteStartObject(); JsonHelper.writeIfNotNullOrEmpty(writer, "doc", this.Doc); if (null != this.Request) this.Request.WriteJsonFields(writer, names, null); if (null != this.Response) { writer.WritePropertyName("response"); Response.WriteJson(writer, names, encspace); } if (null != this.Error) { writer.WritePropertyName("errors"); this.Error.WriteJson(writer, names, encspace); } if (null != Oneway) { writer.WritePropertyName("one-way"); writer.WriteValue(Oneway); } writer.WriteEndObject(); }
/// <summary> /// Writes named schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the named schema</param> protected internal override void WriteJsonFields(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { this.SchemaName.WriteJson(writer, names, encspace); if (null != aliases) { writer.WritePropertyName("aliases"); writer.WriteStartArray(); foreach (SchemaName name in aliases) { string fullname = (null != name.Space) ? name.Space + "." + name.Name : name.Name; writer.WriteValue(fullname); } writer.WriteEndArray(); } }
/// <summary> /// Writes enum schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schema already written</param> /// <param name="encspace">enclosing namespace of the enum schema</param> protected internal override void WriteJsonFields(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { base.WriteJsonFields(writer, names, encspace); writer.WritePropertyName("symbols"); writer.WriteStartArray(); foreach (string s in this.Symbols) writer.WriteValue(s); writer.WriteEndArray(); }
/// <summary> /// Generate list of named schemas from given protocol /// </summary> /// <param name="protocol">protocol to process</param> /// <returns></returns> protected virtual SchemaNames generateNames(Protocol protocol) { var names = new SchemaNames(); foreach (Schema schema in protocol.Types) addName(schema, names); return names; }
/// <summary> /// Default implementation for writing schema properties in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the schema</param> protected internal virtual void WriteJsonFields(JsonTextWriter writer, SchemaNames names, string encspace) { }
/// <summary> /// Static function to return a new instance of the named schema /// </summary> /// <param name="jo">JSON object of the named schema</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the named schema</param> /// <returns></returns> internal static NamedSchema NewInstance(JObject jo, PropertyMap props, SchemaNames names, string encspace) { string type = JsonHelper.GetRequiredString(jo, "type"); switch (type) { case "fixed": return FixedSchema.NewInstance(jo, props, names, encspace); case "enum": return EnumSchema.NewInstance(jo, props, names, encspace); case "record": return RecordSchema.NewInstance(Type.Record, jo, props, names, encspace); case "error": return RecordSchema.NewInstance(Type.Error, jo, props, names, encspace); default: NamedSchema result; if (names.TryGetValue(type, null, encspace, out result)) return result; return null; } }
/// <summary> /// Writes named schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the named schema</param> protected internal override void WriteJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { if (!names.Add(this)) { // schema is already in the list, write name only SchemaName schemaName = this.SchemaName; string name; if (schemaName.Namespace != encspace) name = schemaName.Namespace + "." + schemaName.Name; // we need to add the qualifying namespace of the target schema if it's not the same as current namespace else name = schemaName.Name; writer.WriteValue(name); } else // schema is not in the list, write full schema definition base.WriteJson(writer, names, encspace); }
/// <summary> /// Static function to return new instance of EnumSchema /// </summary> /// <param name="jtok">JSON object for enum schema</param> /// <param name="names">list of named schema already parsed in</param> /// <param name="encspace">enclosing namespace for the enum schema</param> /// <returns>new instance of enum schema</returns> internal static EnumSchema NewInstance(JToken jtok, PropertyMap props, SchemaNames names, string encspace) { SchemaName name = NamedSchema.GetName(jtok, encspace); var aliases = NamedSchema.GetAliases(jtok, name.Space, name.EncSpace); JArray jsymbols = jtok["symbols"] as JArray; if (null == jsymbols) throw new SchemaParseException("Enum has no symbols: " + name); List<string> symbols = new List<string>(); IDictionary<string, int> symbolMap = new Dictionary<string, int>(); int i = 0; foreach (JValue jsymbol in jsymbols) { string s = (string)jsymbol.Value; if (symbolMap.ContainsKey(s)) throw new SchemaParseException("Duplicate symbol: " + s); symbolMap[s] = i++; symbols.Add(s); } return new EnumSchema(name, aliases, symbols, symbolMap, props, names); }
/// <summary> /// Writes the schema name in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the schema</param> internal void WriteJson(Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { if (null != this.Name) // write only if not anonymous { JsonHelper.writeIfNotNullOrEmpty(writer, "name", this.Name); if (!String.IsNullOrEmpty(this.Space)) JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.Space); else if (!String.IsNullOrEmpty(this.EncSpace)) // need to put enclosing name space for code generated classes JsonHelper.writeIfNotNullOrEmpty(writer, "namespace", this.EncSpace); } }
/// <summary> /// Writes primitive schema in JSON format /// </summary> /// <param name="w"></param> /// <param name="names"></param> /// <param name="encspace"></param> protected internal override void WriteJson(JsonTextWriter w, SchemaNames names, string encspace) { w.WriteValue(Name); }
/// <summary> /// Parses a JSON string to create a new schema object /// </summary> /// <param name="json">JSON string</param> /// <param name="names">list of named schemas already read</param> /// <param name="encspace">enclosing namespace of the schema</param> /// <returns>new Schema object</returns> internal static Schema Parse(string json, SchemaNames names, string encspace) { Schema sc = PrimitiveSchema.NewInstance(json); if (null != sc) return sc; try { bool IsArray = json.StartsWith("[") && json.EndsWith("]"); JContainer j = IsArray ? (JContainer)JArray.Parse(json) : (JContainer)JObject.Parse(json); return ParseJson(j, names, encspace); } catch (Newtonsoft.Json.JsonSerializationException ex) { throw new SchemaParseException("Could not parse. " + ex.Message + Environment.NewLine + json); } }
/// <summary> /// Recursively search the given schema for named schemas and adds them to the given container /// </summary> /// <param name="schema">schema object to search</param> /// <param name="names">list of named schemas</param> protected virtual void addName(Schema schema, SchemaNames names) { NamedSchema ns = schema as NamedSchema; if (null != ns) if (names.Contains(ns.SchemaName)) return; switch (schema.Tag) { case Schema.Type.Null: case Schema.Type.Boolean: case Schema.Type.Int: case Schema.Type.Long: case Schema.Type.Float: case Schema.Type.Double: case Schema.Type.Bytes: case Schema.Type.String: break; case Schema.Type.Enumeration: case Schema.Type.Fixed: names.Add(ns); break; case Schema.Type.Record: case Schema.Type.Error: var rs = schema as RecordSchema; names.Add(rs); foreach (Field field in rs.Fields) addName(field.Schema, names); break; case Schema.Type.Array: var asc = schema as ArraySchema; addName(asc.ItemSchema, names); break; case Schema.Type.Map: var ms = schema as MapSchema; addName(ms.ValueSchema, names); break; case Schema.Type.Union: var us = schema as UnionSchema; foreach (Schema usc in us.Schemas) addName(usc, names); break; default: throw new CodeGenException("Unable to add name for " + schema.Name + " type " + schema.Tag); } }
/// <summary> /// Writes union schema in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace of the schema</param> protected internal override void WriteJson(Arch.CMessaging.Client.Newtonsoft.Json.JsonTextWriter writer, SchemaNames names, string encspace) { writer.WriteStartArray(); foreach (Schema schema in this.Schemas) schema.WriteJson(writer, names, encspace); writer.WriteEndArray(); }
/// <summary> /// Generate list of named schemas from given schema /// </summary> /// <param name="schema">schema to process</param> /// <returns></returns> protected virtual SchemaNames generateNames(Schema schema) { var names = new SchemaNames(); addName(schema, names); return names; }
/// <summary> /// Writes the Field class in JSON format /// </summary> /// <param name="writer">JSON writer</param> /// <param name="names">list of named schemas already written</param> /// <param name="encspace">enclosing namespace for the field</param> protected internal void writeJson(JsonTextWriter writer, SchemaNames names, string encspace) { writer.WriteStartObject(); JsonHelper.writeIfNotNullOrEmpty(writer, "name", this.Name); JsonHelper.writeIfNotNullOrEmpty(writer, "doc", this.Documentation); if (null != this.DefaultValue) { writer.WritePropertyName("default"); this.DefaultValue.WriteTo(writer, null); } if (null != this.Schema) { writer.WritePropertyName("type"); Schema.WriteJson(writer, names, encspace); } if (null != this.Props) this.Props.WriteJson(writer); if (null != aliases) { writer.WritePropertyName("aliases"); writer.WriteStartArray(); foreach (string name in aliases) writer.WriteValue(name); writer.WriteEndArray(); } writer.WriteEndObject(); }