/// <summary> /// Checks if this schema can read data written by the given schema. Used for decoding data. /// </summary> /// <param name="writerSchema">writer schema</param> /// <returns>true if this and writer schema are compatible based on the AVRO specification, false otherwise</returns> public override bool CanRead(Schema writerSchema) { if (writerSchema.Tag != Tag) return false; ArraySchema that = writerSchema as ArraySchema; return ItemSchema.CanRead(that.ItemSchema); }
/// <summary> /// Checks if this schema can read data written by the given schema. Used for decoding data. /// </summary> /// <param name="writerSchema">writer schema</param> /// <returns>true if this and writer schema are compatible based on the AVRO specification, false otherwise</returns> public override bool CanRead(Schema writerSchema) { if (writerSchema.Tag != Tag) return false; MapSchema that = writerSchema as MapSchema; return ValueSchema.CanRead(that.ValueSchema); }
public Message(string name, string doc, IList<Parameter> request, Schema response, UnionSchema error) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name", "name cannot be null."); this.Request = request; this.Response = response; this.Error = error; this.Name = name; this.Doc = doc; }
private static object GetValue(IJsonValue value, Schema schema) { switch (value) { case JsonString s: return(s.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Long): return((long)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Float): return((float)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Int): return((int)n.Value); case JsonNumber n: return(n.Value); case JsonBoolean b: return(b.Value); case JsonObject o: { var recordSchema = (RecordSchema)schema; var result = new GenericRecord(recordSchema); foreach (var(key, childValue) in o) { if (recordSchema.TryGetField(key, out var field)) { result.Add(key, GetValue(childValue, field.Schema)); } } return(result); } case JsonArray a: { var arraySchema = (ArraySchema)schema; var result = new List <object>(); foreach (var item in a) { result.Add(GetValue(item, arraySchema.ItemSchema)); } return(result.ToArray()); } } return(null); }
/// <summary> /// Constructor for Message class /// </summary> /// <param name="name">name property</param> /// <param name="doc">doc property</param> /// <param name="request">list of parameters</param> /// <param name="response">response property</param> /// <param name="error">error union schema</param> public Message(string name, string doc, RecordSchema request, Schema response, UnionSchema error, bool? oneway) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name", "name cannot be null."); this.Request = request; this.Response = response; this.Error = error; this.Name = name; this.Doc = doc; this.Oneway = oneway; }
/// <summary> /// A flag to indicate if reader schema has a field that is missing from writer schema and has a default value /// This is set in CanRead() which is always be called before deserializing data /// </summary> /// <summary> /// Constructor for the field class /// </summary> /// <param name="schema">schema for the field type</param> /// <param name="name">name of the field</param> /// <param name="aliases">list of aliases for the name of the field</param> /// <param name="pos">position of the field</param> /// <param name="doc">documentation for the field</param> /// <param name="defaultValue">field's default value if it exists</param> /// <param name="sortorder">sort order of the field</param> internal Field(Schema schema, string name, IList<string> aliases, int pos, string doc, JToken defaultValue, SortOrder sortorder, PropertyMap props) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name", "name cannot be null."); if (null == schema) throw new ArgumentNullException("type", "type cannot be null."); this.Schema = schema; this.Name = name; this.aliases = aliases; this.Pos = pos; this.Documentation = doc; this.DefaultValue = defaultValue; this.Ordering = sortorder; this.Props = props; }
/// <summary> /// Checks if this schema can read data written by the given schema. Used for decoding data. /// </summary> /// <param name="writerSchema">writer schema</param> /// <returns>true if this and writer schema are compatible based on the AVRO specification, false otherwise</returns> public override bool CanRead(Schema writerSchema) { if (writerSchema is UnionSchema || Tag == writerSchema.Tag) return true; Type t = writerSchema.Tag; switch (Tag) { case Type.Double: return t == Type.Int || t == Type.Long || t == Type.Float; case Type.Float: return t == Type.Int || t == Type.Long; case Type.Long: return t == Type.Int; default: return false; } }
private object GetValue(IJsonValue value, Avro.Schema schema) { switch (value) { case JsonString s: return(s.Value); case JsonNumber n: return(n.Value); case JsonBoolean b: return(b.Value); case JsonObject o: { var recordSchema = (RecordSchema)schema; var result = new GenericRecord(recordSchema); foreach (var(key, childValue) in o) { if (recordSchema.TryGetField(key, out var field)) { result.Add(key, GetValue(childValue, field.Schema)); } } return(result); } case JsonArray a: { var arraySchema = (ArraySchema)schema; var result = new List <object>(); foreach (var item in a) { result.Add(GetValue(item, arraySchema.ItemSchema)); } return(result.ToArray()); } } return(null); }
private GenericRecord CreateAvroRecord(string json, string avroSchema) { try { var schema = (RecordSchema)Schema.Parse(avroSchema); var jsonObject = jsonSerializer.Deserialize <JsonObject>(json); var result = (GenericRecord)GetValue(jsonObject, schema); return(result); } catch (JsonException ex) { throw new InvalidOperationException($"Failed to parse json: {json}, got {ex.Message}", ex); } }
public AvroSerializer(string schema, bool isPath) { if (isPath) { var fullPath = Path.GetFullPath(schema); if (File.Exists(fullPath)) { Schema = Avro.RecordSchema.Parse(File.ReadAllText(fullPath)); } } else { if (!string.IsNullOrEmpty(schema)) { Schema = RecordSchema.Parse(schema); } } }
/// <summary> /// Returns <see cref="Fingerprint64(byte[])"/> applied to the parsing canonical form of the supplied schema. /// </summary> /// <param name="s">Schema to be hashed.</param> /// <returns>Fingerprint</returns> public static long ParsingFingerprint64(Schema s) { return(Fingerprint64(Encoding.UTF8.GetBytes(ToParsingForm(s)))); }
private static void testEquality(string s, Schema sc) { Assert.IsTrue(sc.Equals(sc)); Schema sc2 = Schema.Parse(s); Assert.IsTrue(sc.Equals(sc2)); Assert.AreEqual(sc.GetHashCode(), sc2.GetHashCode()); }
public AvroSerializer(Avro.Schema schema) { Schema = schema; }
protected virtual void createSchemaJavaField(Schema schema, CodeTypeDeclaration ctd, bool overrideFlag, bool isInterface) { // create schema field var ctrfield = new CodeTypeReference("org.apache.avro.Schema"); string schemaFname = "SCHEMA$"; var codeField = new CodeMemberField(ctrfield, schemaFname); codeField.Attributes = MemberAttributes.Public | MemberAttributes.Static | MemberAttributes.Final; if (isInterface) { codeField.Attributes = MemberAttributes.Public | MemberAttributes.Final | MemberAttributes.Const; } // create function call Schema.Parse(json) var cpe = new CodePrimitiveExpression(schema.ToString()); var cmie = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(ctrfield), "parse"), new CodeExpression[] { cpe }); codeField.InitExpression = cmie; ctd.Members.Add(codeField); if (isInterface) { return; } // create property to get static schema field var property = new CodeMemberMethod(); property.Attributes = MemberAttributes.Public; if (overrideFlag) property.Attributes |= MemberAttributes.Override; property.Name = "getSchema"; property.ReturnType = ctrfield; property.Statements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression(ctd.Name + "." + schemaFname))); ctd.Members.Add(property); // create property to get ther record type property = new CodeMemberMethod(); property.Attributes = MemberAttributes.Public; if (overrideFlag) property.Attributes |= MemberAttributes.Override; property.Name = "getRecord"; property.ReturnType = new CodeTypeReference(ctd.Name); property.Statements.Add(new CodeMethodReturnStatement(new CodeThisReferenceExpression())); ctd.Members.Add(property); }
/// <summary> /// Creates an interface declaration /// </summary> /// <param name="schema">record schema</param> /// <param name="ns">namespace</param> /// <returns></returns> protected virtual CodeTypeDeclaration processRecordInterface(Schema schema) { RecordSchema recordSchema = schema as RecordSchema; if (null == recordSchema) throw new CodeGenException("Unable to cast schema into a record"); string recordSchemaName = recordSchema.Name; recordSchemaName = recordSchemaName.Substring(0, recordSchemaName.Length - "Record".Length); // declare the class var ctd = new CodeTypeDeclaration(CodeGenUtil.Instance.Mangle(recordSchemaName)); ctd.Attributes = MemberAttributes.Public; ctd.IsInterface = true; createSchemaField(schema, ctd, false, true); foreach (Field field in recordSchema.Fields) { // Determine type of field bool nullibleEnum = false; string baseType = getType(field.Schema, false, ref nullibleEnum, false); var ctrfield = new CodeTypeReference(baseType); // Process field documentation if it exist and add to the field CodeCommentStatement propertyComment = null; if (!string.IsNullOrEmpty(field.Documentation)) { propertyComment = createDocComment(field.Documentation); } // Create reference to the field - this.fieldname CodeFieldReferenceExpression fieldRef = null; var mangledName = CodeGenUtil.Instance.Mangle(field.Name); // Create field property with get and set methods AddProperty(ctd, ctrfield, propertyComment, mangledName, fieldRef, true); } string nspace = recordSchema.Namespace; if (string.IsNullOrEmpty(nspace)) throw new CodeGenException("Namespace required for record schema " + recordSchema.Name); CodeNamespace codens = addNamespace(nspace); codens.Types.Add(ctd); return ctd; }
public SchemaResolutionException(string s, Schema readerSchema, Schema writerSchema) : base(s) { }
/// <summary> /// Creates a new <see cref="MapSchema"/> from the given schema. /// </summary> /// <param name="type">Schema to create the map schema from.</param> /// <returns>A new <see cref="MapSchema"/>.</returns> public static MapSchema CreateMap(Schema type) { return(new MapSchema(type, null)); }
private static object GetValue(IJsonValue value, Schema schema) { switch (value) { case JsonString s when IsTypeOrUnionWith(schema, Schema.Type.String): return(s.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Long): return((long)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Float): return((float)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Int): return((int)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Double): return(n.Value); case JsonBoolean b when IsTypeOrUnionWith(schema, Schema.Type.Boolean): return(b.Value); case JsonObject o when IsTypeOrUnionWith(schema, Schema.Type.Map): { var mapResult = new Dictionary <string, object>(); if (schema is UnionSchema union) { var map = (MapSchema)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Map); foreach (var(key, childValue) in o) { mapResult.Add(key, GetValue(childValue, map?.ValueSchema)); } } else if (schema is MapSchema map) { foreach (var(key, childValue) in o) { mapResult.Add(key, GetValue(childValue, map?.ValueSchema)); } } return(mapResult); } case JsonObject o when IsTypeOrUnionWith(schema, Schema.Type.Record): { GenericRecord result = null; if (schema is UnionSchema union) { var record = (RecordSchema)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Record); result = new GenericRecord(record); foreach (var(key, childValue) in o) { if (record != null && record.TryGetField(key, out var field)) { result.Add(key, GetValue(childValue, field.Schema)); } } } else if (schema is RecordSchema record) { result = new GenericRecord(record); foreach (var(key, childValue) in o) { if (record.TryGetField(key, out var field)) { result.Add(key, GetValue(childValue, field.Schema)); } } } return(result); } case JsonArray a when IsTypeOrUnionWith(schema, Schema.Type.Array): { var result = new List <object>(); if (schema is UnionSchema union) { var arraySchema = (ArraySchema)union.Schemas.FirstOrDefault(x => x.Tag == Schema.Type.Array); foreach (var item in a) { result.Add(GetValue(item, arraySchema?.ItemSchema)); } } else if (schema is ArraySchema array) { foreach (var item in a) { result.Add(GetValue(item, array.ItemSchema)); } } return(result.ToArray()); } } return(null); }
/// <summary> /// Parses a schema into the canonical form as defined by Avro spec. /// </summary> /// <param name="s">Schema</param> /// <returns>Parsing Canonical Form of a schema as defined by Avro spec.</returns> public static string ToParsingForm(Schema s) { IDictionary <string, string> env = new Dictionary <string, string>(); return(Build(env, s, new StringBuilder()).ToString()); }
private static StringBuilder Build(IDictionary <string, string> env, Schema s, StringBuilder o) { bool firstTime = true; Schema.Type st = s.Tag; switch (st) { case Schema.Type.Union: UnionSchema us = s as UnionSchema; o.Append('['); foreach (Schema b in us.Schemas) { if (!firstTime) { o.Append(","); } else { firstTime = false; } Build(env, b, o); } return(o.Append(']')); case Schema.Type.Array: case Schema.Type.Map: o.Append("{\"type\":\"").Append(Schema.GetTypeString(s.Tag)).Append("\""); if (st == Schema.Type.Array) { ArraySchema arraySchema = s as ArraySchema; Build(env, arraySchema.ItemSchema, o.Append(",\"items\":")); } else { MapSchema mapSchema = s as MapSchema; Build(env, mapSchema.ValueSchema, o.Append(",\"values\":")); } return(o.Append("}")); case Schema.Type.Enumeration: case Schema.Type.Fixed: case Schema.Type.Record: NamedSchema namedSchema = s as NamedSchema; var name = namedSchema.Fullname; if (env.ContainsKey(name)) { return(o.Append(env[name])); } var qname = "\"" + name + "\""; env.Add(name, qname); o.Append("{\"name\":").Append(qname); o.Append(",\"type\":\"").Append(Schema.GetTypeString(s.Tag)).Append("\""); if (st == Schema.Type.Enumeration) { EnumSchema enumSchema = s as EnumSchema; o.Append(",\"symbols\":["); foreach (var enumSymbol in enumSchema.Symbols) { if (!firstTime) { o.Append(","); } else { firstTime = false; } o.Append("\"").Append(enumSymbol).Append("\""); } o.Append("]"); } else if (st == Schema.Type.Fixed) { FixedSchema fixedSchema = s as FixedSchema; o.Append(",\"size\":") .Append(fixedSchema.Size.ToString(CultureInfo.InvariantCulture)); } else // st == Schema.Type.Record { RecordSchema recordSchema = s as RecordSchema; o.Append(",\"fields\":["); foreach (var field in recordSchema.Fields) { if (!firstTime) { o.Append(","); } else { firstTime = false; } o.Append("{\"name\":\"").Append(field.Name).Append("\""); Build(env, field.Schema, o.Append(",\"type\":")).Append("}"); } o.Append("]"); } return(o.Append("}")); default: //boolean, bytes, double, float, int, long, null, string return(o.Append("\"").Append(s.Name).Append("\"")); } }
private static object GetValue(IJsonValue value, Schema schema) { switch (value) { case JsonString s: return(s.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Long): return((long)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Float): return((float)n.Value); case JsonNumber n when IsTypeOrUnionWith(schema, Schema.Type.Int): return((int)n.Value); case JsonNumber n: return(n.Value); case JsonBoolean b: return(b.Value); case JsonObject o when(schema is MapSchema map): { var mapResult = new Dictionary <string, object>(); foreach (var(key, childValue) in o) { mapResult.Add(key, GetValue(childValue, map.ValueSchema)); } return(mapResult); } case JsonObject o when(schema is RecordSchema record): { var result = new GenericRecord(record); foreach (var(key, childValue) in o) { if (record.TryGetField(key, out var field)) { result.Add(key, GetValue(childValue, field.Schema)); } } return(result); } case JsonArray a when(schema is ArraySchema array): { var result = new List <object>(); foreach (var item in a) { result.Add(GetValue(item, array.ItemSchema)); } return(result.ToArray()); } } return(null); }
/// <summary> /// Returns <see cref="Fingerprint(string, byte[])"/> applied to the parsing canonical form of the supplied schema. /// </summary> /// <param name="fpName">Name of the hashing algorithm.</param> /// <param name="s">Schema to be hashed.</param> /// <returns>Fingerprint</returns> public static byte[] ParsingFingerprint(string fpName, Schema s) { return Fingerprint(fpName, Encoding.UTF8.GetBytes(ToParsingForm(s))); }
/// <summary> /// Checks if this schema can read data written by the given schema. Used for decoding data. /// </summary> /// <param name="writerSchema">writer schema</param> /// <returns>true if this and writer schema are compatible based on the AVRO specification, false otherwise</returns> public override bool CanRead(Schema writerSchema) { if (writerSchema.Tag != Tag) return false; FixedSchema that = writerSchema as FixedSchema; if (that.Size != Size) return false; if (that.SchemaName.Equals(SchemaName)) return true; else return InAliases(that.SchemaName); }
/// <summary> /// Returns <see cref="Fingerprint64(byte[])"/> applied to the parsing canonical form of the supplied schema. /// </summary> /// <param name="s">Schema to be hashed.</param> /// <returns>Fingerprint</returns> public static long ParsingFingerprint64(Schema s) { return Fingerprint64(Encoding.UTF8.GetBytes(ToParsingForm(s))); }
internal static string getTypeJava(Schema schema, bool nullible, ref bool nullibleEnum, bool forUnion) { switch (schema.Tag) { case Schema.Type.Null: return "Object"; case Schema.Type.Boolean: if (nullible) return "Boolean"; else return "boolean"; case Schema.Type.Int: if (nullible) return "Integer"; else return "int"; case Schema.Type.Long: if (nullible) return "Long"; else return "long"; case Schema.Type.Float: if (nullible) return "Float"; else return "float"; case Schema.Type.Double: if (nullible) return "Double"; else return "double"; case Schema.Type.Bytes: return "int[]"; case Schema.Type.String: return "String"; case Schema.Type.Enumeration: var namedSchema = schema as NamedSchema; if (null == namedSchema) throw new CodeGenException("Unable to cast schema into a named schema"); if (nullible) { nullibleEnum = true; return "System.Nullable<" + CodeGenUtil.Instance.Mangle(namedSchema.Fullname) + ">"; } else return CodeGenUtil.Instance.Mangle(namedSchema.Fullname); case Schema.Type.Fixed: case Schema.Type.Record: case Schema.Type.Error: namedSchema = schema as NamedSchema; if (null == namedSchema) throw new CodeGenException("Unable to cast schema into a named schema"); return CodeGenUtil.Instance.Mangle(namedSchema.Fullname); case Schema.Type.Array: var arraySchema = schema as ArraySchema; if (null == arraySchema) throw new CodeGenException("Unable to cast schema into an array schema"); return "" + getType(arraySchema.ItemSchema, false, ref nullibleEnum, forUnion) + "[]"; case Schema.Type.Map: var mapSchema = schema as MapSchema; if (null == mapSchema) throw new CodeGenException("Unable to cast schema into a map schema"); return "IDictionary<string," + getType(mapSchema.ValueSchema, false, ref nullibleEnum, forUnion) + ">"; case Schema.Type.Union: var unionSchema = schema as UnionSchema; if (null == unionSchema) throw new CodeGenException("Unable to cast schema into a union schema"); Schema nullibleType = getNullableType(unionSchema); if (null == nullibleType) return SystemObjectStr; else return getType(nullibleType, true, ref nullibleEnum, true); } throw new CodeGenException("Unable to generate CodeTypeReference for " + schema.Name + " type " + schema.Tag); }
private static bool IsTypeOrUnionWith(Schema schema, Schema.Type expected) { return(schema.Tag == expected || (schema is UnionSchema union && union.Schemas.Any(x => x.Tag == expected))); }
/// <summary> /// Constructor for map schema class /// </summary> /// <param name="valueSchema">schema for map values type</param> private MapSchema(Schema valueSchema, PropertyMap props) : base(Type.Map, props) { if (null == valueSchema) throw new ArgumentNullException("valueSchema", "valueSchema cannot be null."); this.ValueSchema = valueSchema; }
/// <summary> /// Parses a schema into the canonical form as defined by Avro spec. /// </summary> /// <param name="s">Schema</param> /// <returns>Parsing Canonical Form of a schema as defined by Avro spec.</returns> public static string ToParsingForm(Schema s) { IDictionary<string, string> env = new Dictionary<string, string>(); return Build(env, s, new StringBuilder()).ToString(); }
public void TestPrimitive(string s, Schema.Type type) { Schema sc = Schema.Parse(s); Assert.IsTrue(sc is PrimitiveSchema); Assert.AreEqual(type, sc.Tag); testEquality(s, sc); testToString(sc); }
public SpecificSerializerImpl( ISchemaRegistryClient schemaRegistryClient, bool autoRegisterSchema, int initialBufferSize, bool isKey) { this.schemaRegistryClient = schemaRegistryClient; this.autoRegisterSchema = autoRegisterSchema; this.initialBufferSize = initialBufferSize; this.isKey = isKey; Type writerType = typeof(T); if (typeof(ISpecificRecord).IsAssignableFrom(writerType)) { writerSchema = (Avro.Schema) typeof(T).GetField("_SCHEMA", BindingFlags.Public | BindingFlags.Static).GetValue(null); } else if (writerType.Equals(typeof(int))) { writerSchema = Avro.Schema.Parse("int"); } else if (writerType.Equals(typeof(bool))) { writerSchema = Avro.Schema.Parse("boolean"); } else if (writerType.Equals(typeof(double))) { writerSchema = Avro.Schema.Parse("double"); } else if (writerType.Equals(typeof(string))) { // Note: It would arguably be better to make this a union with null, to // exactly match the .NET string type, however we don't for consistency // with the Java avro serializer. writerSchema = Avro.Schema.Parse("string"); } else if (writerType.Equals(typeof(float))) { writerSchema = Avro.Schema.Parse("float"); } else if (writerType.Equals(typeof(long))) { writerSchema = Avro.Schema.Parse("long"); } else if (writerType.Equals(typeof(byte[]))) { // Note: It would arguably be better to make this a union with null, to // exactly match the .NET byte[] type, however we don't for consistency // with the Java avro serializer. writerSchema = Avro.Schema.Parse("bytes"); } else { throw new ArgumentException( $"{nameof(AvroSerializer<T>)} " + "only accepts type parameters of int, bool, double, string, float, " + "long, byte[], instances of ISpecificRecord and subclasses of SpecificFixed." ); } avroWriter = new SpecificWriter <T>(writerSchema); writerSchemaString = writerSchema.ToString(); }
private static void testToString(Schema sc) { try { Assert.AreEqual(sc, Schema.Parse(sc.ToString())); } catch (Exception e) { throw new AvroException(e.ToString() + ": " + sc.ToString()); } }
/// <summary> /// Constructor /// </summary> /// <param name="items">schema for the array items type</param> private ArraySchema(Schema items, PropertyMap props) : base(Type.Array, props) { if (null == items) throw new ArgumentNullException("items"); this.ItemSchema = items; }
private static StringBuilder Build(IDictionary<string, string> env, Schema s, StringBuilder o) { bool firstTime = true; Schema.Type st = s.Tag; switch (st) { case Schema.Type.Union: UnionSchema us = s as UnionSchema; o.Append('['); foreach(Schema b in us.Schemas) { if (!firstTime) { o.Append(","); } else { firstTime = false; } Build(env, b, o); } return o.Append(']'); case Schema.Type.Array: case Schema.Type.Map: o.Append("{\"type\":\"").Append(Schema.GetTypeString(s.Tag)).Append("\""); if (st == Schema.Type.Array) { ArraySchema arraySchema = s as ArraySchema; Build(env, arraySchema.ItemSchema, o.Append(",\"items\":")); } else { MapSchema mapSchema = s as MapSchema; Build(env, mapSchema.ValueSchema, o.Append(",\"values\":")); } return o.Append("}"); case Schema.Type.Enumeration: case Schema.Type.Fixed: case Schema.Type.Record: NamedSchema namedSchema = s as NamedSchema; var name = namedSchema.Fullname; if (env.ContainsKey(name)) { return o.Append(env[name]); } var qname = "\"" + name + "\""; env.Add(name, qname); o.Append("{\"name\":").Append(qname); o.Append(",\"type\":\"").Append(Schema.GetTypeString(s.Tag)).Append("\""); if (st == Schema.Type.Enumeration) { EnumSchema enumSchema = s as EnumSchema; o.Append(",\"symbols\":["); foreach (var enumSymbol in enumSchema.Symbols) { if (!firstTime) { o.Append(","); } else { firstTime = false; } o.Append("\"").Append(enumSymbol).Append("\""); } o.Append("]"); } else if (st == Schema.Type.Fixed) { FixedSchema fixedSchema = s as FixedSchema; o.Append(",\"size\":").Append(fixedSchema.Size.ToString()); } else // st == Schema.Type.Record { RecordSchema recordSchema = s as RecordSchema; o.Append(",\"fields\":["); foreach (var field in recordSchema.Fields) { if (!firstTime) { o.Append(","); } else { firstTime = false; } o.Append("{\"name\":\"").Append(field.Name).Append("\""); Build(env, field.Schema, o.Append(",\"type\":")).Append("}"); } o.Append("]"); } return o.Append("}"); default: //boolean, bytes, double, float, int, long, null, string return o.Append("\"").Append(s.Name).Append("\""); } }
/// <summary> /// Returns <see cref="Fingerprint(string, byte[])"/> applied to the parsing canonical form of the supplied schema. /// </summary> /// <param name="fpName">Name of the hashing algorithm.</param> /// <param name="s">Schema to be hashed.</param> /// <returns>Fingerprint</returns> public static byte[] ParsingFingerprint(string fpName, Schema s) { return(Fingerprint(fpName, Encoding.UTF8.GetBytes(ToParsingForm(s)))); }
/// <summary> /// Creates a class declaration /// </summary> /// <param name="schema">record schema</param> /// <param name="ns">namespace</param> /// <returns></returns> protected virtual CodeTypeDeclaration processRecord(Schema schema) { RecordSchema recordSchema = schema as RecordSchema; if (null == recordSchema) throw new CodeGenException("Unable to cast schema into a record"); // declare the class var ctd = new CodeTypeDeclaration(CodeGenUtil.Instance.Mangle(recordSchema.Name)); ctd.BaseTypes.Add("ISpecificRecord"); ctd.Attributes = MemberAttributes.Public; ctd.IsClass = true; ctd.IsPartial = true; createSchemaField(schema, ctd, false); // declare Get() to be used by the Writer classes var cmmGet = new CodeMemberMethod(); cmmGet.Name = "Get"; cmmGet.Attributes = MemberAttributes.Public; cmmGet.ReturnType = new CodeTypeReference("System.Object"); cmmGet.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "fieldPos")); StringBuilder getFieldStmt = new StringBuilder("switch (fieldPos)\n\t\t\t{\n"); // declare Put() to be used by the Reader classes var cmmPut = new CodeMemberMethod(); cmmPut.Name = "Put"; cmmPut.Attributes = MemberAttributes.Public; cmmPut.ReturnType = new CodeTypeReference(typeof(void)); cmmPut.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "fieldPos")); cmmPut.Parameters.Add(new CodeParameterDeclarationExpression("System.Object", "fieldValue")); var putFieldStmt = new StringBuilder("switch (fieldPos)\n\t\t\t{\n"); foreach (Field field in recordSchema.Fields) { // Determine type of field bool nullibleEnum = false; string baseType = getType(field.Schema, false, ref nullibleEnum); var ctrfield = new CodeTypeReference(baseType); // Create field string privFieldName = string.Concat("_", field.Name); var codeField = new CodeMemberField(ctrfield, privFieldName); codeField.Attributes = MemberAttributes.Private; // Process field documentation if it exist and add to the field CodeCommentStatement propertyComment = null; if (!string.IsNullOrEmpty(field.Documentation)) { propertyComment = createDocComment(field.Documentation); if (null != propertyComment) codeField.Comments.Add(propertyComment); } // Add field to class ctd.Members.Add(codeField); // Create reference to the field - this.fieldname var fieldRef = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), privFieldName); var mangledName = CodeGenUtil.Instance.Mangle(field.Name); // Create field property with get and set methods var property = new CodeMemberProperty(); property.Attributes = MemberAttributes.Public | MemberAttributes.Final; property.Name = mangledName; property.Type = ctrfield; property.GetStatements.Add(new CodeMethodReturnStatement(fieldRef)); property.SetStatements.Add(new CodeAssignStatement(fieldRef, new CodePropertySetValueReferenceExpression())); if (null != propertyComment) property.Comments.Add(propertyComment); // Add field property to class ctd.Members.Add(property); // add to Get() getFieldStmt.Append("\t\t\tcase "); getFieldStmt.Append(field.Pos); getFieldStmt.Append(": return this."); getFieldStmt.Append(mangledName); getFieldStmt.Append(";\n"); // add to Put() putFieldStmt.Append("\t\t\tcase "); putFieldStmt.Append(field.Pos); putFieldStmt.Append(": this."); putFieldStmt.Append(mangledName); if (nullibleEnum) { putFieldStmt.Append(" = fieldValue == null ? ("); putFieldStmt.Append(baseType); putFieldStmt.Append(")null : ("); string type = baseType.Remove(0, 16); // remove System.Nullable< type = type.Remove(type.Length - 1); // remove > putFieldStmt.Append(type); putFieldStmt.Append(")fieldValue; break;\n"); } else { putFieldStmt.Append(" = ("); putFieldStmt.Append(baseType); putFieldStmt.Append(")fieldValue; break;\n"); } } // end switch block for Get() getFieldStmt.Append("\t\t\tdefault: throw new AvroRuntimeException(\"Bad index \" + fieldPos + \" in Get()\");\n\t\t\t}"); var cseGet = new CodeSnippetExpression(getFieldStmt.ToString()); cmmGet.Statements.Add(cseGet); ctd.Members.Add(cmmGet); // end switch block for Put() putFieldStmt.Append("\t\t\tdefault: throw new AvroRuntimeException(\"Bad index \" + fieldPos + \" in Put()\");\n\t\t\t}"); var csePut = new CodeSnippetExpression(putFieldStmt.ToString()); cmmPut.Statements.Add(csePut); ctd.Members.Add(cmmPut); string nspace = recordSchema.Namespace; if (string.IsNullOrEmpty(nspace)) throw new CodeGenException("Namespace required for record schema " + recordSchema.Name); CodeNamespace codens = addNamespace(nspace); codens.Types.Add(ctd); return ctd; }
/// <summary> /// Creates a class declaration for fixed schema /// </summary> /// <param name="schema">fixed schema</param> /// <param name="ns">namespace object</param> protected virtual void processFixed(Schema schema) { FixedSchema fixedSchema = schema as FixedSchema; if (null == fixedSchema) throw new CodeGenException("Unable to cast schema into a fixed"); CodeTypeDeclaration ctd = new CodeTypeDeclaration(); ctd.Name = CodeGenUtil.Instance.Mangle(fixedSchema.Name); ctd.IsClass = true; ctd.IsPartial = true; ctd.Attributes = MemberAttributes.Public; ctd.BaseTypes.Add("SpecificFixed"); // create static schema field createSchemaField(schema, ctd, true); // Add Size field string sizefname = "fixedSize"; var ctrfield = new CodeTypeReference(typeof(uint)); var codeField = new CodeMemberField(ctrfield, sizefname); codeField.Attributes = MemberAttributes.Private | MemberAttributes.Static; codeField.InitExpression = new CodePrimitiveExpression(fixedSchema.Size); ctd.Members.Add(codeField); // Add Size property var fieldRef = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), sizefname); var property = new CodeMemberProperty(); property.Attributes = MemberAttributes.Public | MemberAttributes.Static; property.Name = "FixedSize"; property.Type = ctrfield; property.GetStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression(schema.Name + "." + sizefname))); ctd.Members.Add(property); // create constructor to initiate base class SpecificFixed CodeConstructor cc = new CodeConstructor(); cc.Attributes = MemberAttributes.Public; cc.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(sizefname)); ctd.Members.Add(cc); string nspace = fixedSchema.Namespace; if (string.IsNullOrEmpty(nspace)) throw new CodeGenException("Namespace required for enum schema " + fixedSchema.Name); CodeNamespace codens = addNamespace(nspace); codens.Types.Add(ctd); }
public static MapSchema CreateMap(Schema type) { return new MapSchema(type,null); }
/// <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> /// Creates an enum declaration /// </summary> /// <param name="schema">enum schema</param> /// <param name="ns">namespace</param> protected virtual void processEnum(Schema schema) { EnumSchema enumschema = schema as EnumSchema; if (null == enumschema) throw new CodeGenException("Unable to cast schema into an enum"); CodeTypeDeclaration ctd = new CodeTypeDeclaration(CodeGenUtil.Instance.Mangle(enumschema.Name)); ctd.IsEnum = true; ctd.Attributes = MemberAttributes.Public; foreach (string symbol in enumschema.Symbols) { if (CodeGenUtil.Instance.ReservedKeywords.Contains(symbol)) throw new CodeGenException("Enum symbol " + symbol + " is a C# reserved keyword"); CodeMemberField field = new CodeMemberField(typeof(int), symbol); ctd.Members.Add(field); } string nspace = enumschema.Namespace; if (string.IsNullOrEmpty(nspace)) throw new CodeGenException("Namespace required for enum schema " + enumschema.Name); CodeNamespace codens = addNamespace(nspace); codens.Types.Add(ctd); }
/// <summary> /// Creates the static schema field for class types /// </summary> /// <param name="schema">schema</param> /// <param name="ctd">CodeTypeDeclaration for the class</param> protected virtual void createSchemaField(Schema schema, CodeTypeDeclaration ctd, bool overrideFlag) { // create schema field var ctrfield = new CodeTypeReference("Schema"); string schemaFname = "_SCHEMA"; var codeField = new CodeMemberField(ctrfield, schemaFname); codeField.Attributes = MemberAttributes.Public | MemberAttributes.Static; // create function call Schema.Parse(json) var cpe = new CodePrimitiveExpression(schema.ToString()); var cmie = new CodeMethodInvokeExpression( new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(Schema)), "Parse"), new CodeExpression[] { cpe }); codeField.InitExpression = cmie; ctd.Members.Add(codeField); // create property to get static schema field var property = new CodeMemberProperty(); property.Attributes = MemberAttributes.Public; if (overrideFlag) property.Attributes |= MemberAttributes.Override; property.Name = "Schema"; property.Type = ctrfield; property.GetStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression(ctd.Name + "." + schemaFname))); ctd.Members.Add(property); }
/// <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> /// Gets the string representation of the schema's data type /// </summary> /// <param name="schema">schema</param> /// <param name="nullible">flag to indicate union with null</param> /// <returns></returns> internal static string getType(Schema schema, bool nullible, ref bool nullibleEnum) { switch (schema.Tag) { case Schema.Type.Null: return "System.Object"; case Schema.Type.Boolean: if (nullible) return "System.Nullable<bool>"; else return typeof(bool).ToString(); case Schema.Type.Int: if (nullible) return "System.Nullable<int>"; else return typeof(int).ToString(); case Schema.Type.Long: if (nullible) return "System.Nullable<long>"; else return typeof(long).ToString(); case Schema.Type.Float: if (nullible) return "System.Nullable<float>"; else return typeof(float).ToString(); case Schema.Type.Double: if (nullible) return "System.Nullable<double>"; else return typeof(double).ToString(); case Schema.Type.Bytes: return typeof(byte[]).ToString(); case Schema.Type.String: return typeof(string).ToString(); case Schema.Type.Enumeration: var namedSchema = schema as NamedSchema; if (null == namedSchema) throw new CodeGenException("Unable to cast schema into a named schema"); if (nullible) { nullibleEnum = true; return "System.Nullable<" + CodeGenUtil.Instance.Mangle(namedSchema.Fullname) + ">"; } else return CodeGenUtil.Instance.Mangle(namedSchema.Fullname); case Schema.Type.Fixed: case Schema.Type.Record: case Schema.Type.Error: namedSchema = schema as NamedSchema; if (null == namedSchema) throw new CodeGenException("Unable to cast schema into a named schema"); return CodeGenUtil.Instance.Mangle(namedSchema.Fullname); case Schema.Type.Array: var arraySchema = schema as ArraySchema; if (null == arraySchema) throw new CodeGenException("Unable to cast schema into an array schema"); return "IList<" + getType(arraySchema.ItemSchema, false, ref nullibleEnum) + ">"; case Schema.Type.Map: var mapSchema = schema as MapSchema; if (null == mapSchema) throw new CodeGenException("Unable to cast schema into a map schema"); return "IDictionary<string," + getType(mapSchema.ValueSchema, false, ref nullibleEnum) + ">"; case Schema.Type.Union: var unionSchema = schema as UnionSchema; if (null == unionSchema) throw new CodeGenException("Unable to cast schema into a union schema"); Schema nullibleType = getNullableType(unionSchema); if (null == nullibleType) return CodeGenUtil.Object; else return getType(nullibleType, true, ref nullibleEnum); } throw new CodeGenException("Unable to generate CodeTypeReference for " + schema.Name + " type " + schema.Tag); }
/// <summary> /// Adds a schema object to generate code for /// </summary> /// <param name="schema">schema object</param> public virtual void AddSchema(Schema schema) { Schemas.Add(schema); }
/// <summary> /// Constructor for Message class /// </summary> /// <param name="name">name property</param> /// <param name="doc">doc property</param> /// <param name="request">list of parameters</param> /// <param name="response">response property</param> /// <param name="error">error union schema</param> public Message(string name, string doc, RecordSchema request, Schema response, UnionSchema error, bool? oneway) { if (string.IsNullOrEmpty(name)) throw new ArgumentNullException("name", "name cannot be null."); this.Request = request; this.Response = response; this.Error = error; this.Name = name; this.Doc = doc; this.Oneway = oneway; if (error != null && error.CanRead(Schema.Parse("string"))) { this.SupportedErrors = error; } else { this.SupportedErrors = (UnionSchema) Schema.Parse("[\"string\"]"); if (error != null) { for (int i = 0; i < error.Schemas.Count; ++i) { this.SupportedErrors.Schemas.Add(error.Schemas[i]); } } } }