in lang/csharp/src/apache/main/CodeGen/CodeGen.cs [738:899]
protected virtual CodeTypeDeclaration processRecord(Schema schema)
{
RecordSchema recordSchema = schema as RecordSchema;
if (recordSchema == null)
{
throw new CodeGenException("Unable to cast schema into a record");
}
bool isError = recordSchema.Tag == Schema.Type.Error;
// declare the class
var ctd = new CodeTypeDeclaration(CodeGenUtil.Instance.Mangle(recordSchema.Name));
var baseTypeReference = new CodeTypeReference(
isError ? typeof(Specific.SpecificException) : typeof(Specific.ISpecificRecord),
CodeTypeReferenceOptions.GlobalReference);
ctd.BaseTypes.Add(baseTypeReference);
ctd.CustomAttributes.Add(CodeGenUtil.Instance.GeneratedCodeAttribute);
ctd.Attributes = MemberAttributes.Public;
ctd.IsClass = true;
ctd.IsPartial = true;
if (recordSchema.Documentation != null)
{
ctd.Comments.Add(createDocComment(recordSchema.Documentation));
}
createSchemaField(schema, ctd, isError);
// 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)")
.AppendLine().AppendLine("\t\t\t{");
// 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)")
.AppendLine().AppendLine("\t\t\t{");
if (isError)
{
cmmGet.Attributes |= MemberAttributes.Override;
cmmPut.Attributes |= MemberAttributes.Override;
}
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;
if (field.Schema is EnumSchema es && es.Default != null)
{
codeField.InitExpression = new CodeTypeReferenceExpression($"{es.Namespace}.{es.Name}.{es.Default}");
}
// Process field documentation if it exist and add to the field
CodeCommentStatement propertyComment = null;
if (!string.IsNullOrEmpty(field.Documentation))
{
propertyComment = createDocComment(field.Documentation);
if (propertyComment != null)
{
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 (propertyComment != null)
{
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.AppendLine(";");
// 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.AppendLine(")fieldValue; break;");
}
else
{
putFieldStmt.Append(" = (");
putFieldStmt.Append(baseType);
putFieldStmt.AppendLine(")fieldValue; break;");
}
}
// end switch block for Get()
getFieldStmt.AppendLine("\t\t\tdefault: throw new global::Avro.AvroRuntimeException(\"Bad index \" + fieldPos + \" in Get()\");")
.Append("\t\t\t}");
var cseGet = new CodeSnippetExpression(getFieldStmt.ToString());
cmmGet.Statements.Add(cseGet);
ctd.Members.Add(cmmGet);
// end switch block for Put()
putFieldStmt.AppendLine("\t\t\tdefault: throw new global::Avro.AvroRuntimeException(\"Bad index \" + fieldPos + \" in Put()\");")
.Append("\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;
}