Kinetica   C#   API  Version 7.2.3.0
CodeGen.cs
Go to the documentation of this file.
1 
18 using System;
19 using System.Collections.Generic;
20 using System.Linq;
21 using System.Reflection;
22 using System.Text;
23 using System.CodeDom;
24 using System.CodeDom.Compiler;
25 using Microsoft.CSharp;
26 using System.IO;
27 
28 namespace Avro
29 {
30  public class CodeGen
31  {
35  public CodeCompileUnit CompileUnit { get; private set; }
36 
40  public IList<Schema> Schemas { get; private set; }
41 
45  public IList<Protocol> Protocols { get; private set; }
46 
50  protected Dictionary<string, CodeNamespace> namespaceLookup = new Dictionary<string, CodeNamespace>(StringComparer.Ordinal);
51 
55  public CodeGen()
56  {
57  this.Schemas = new List<Schema>();
58  this.Protocols = new List<Protocol>();
59  }
60 
65  public virtual void AddProtocol(Protocol protocol)
66  {
67  Protocols.Add(protocol);
68  }
69 
74  public virtual void AddSchema(Schema schema)
75  {
76  Schemas.Add(schema);
77  }
78 
84  protected virtual CodeNamespace addNamespace(string name)
85  {
86  if (string.IsNullOrEmpty(name))
87  throw new ArgumentNullException("name", "name cannot be null.");
88 
89  CodeNamespace ns = null;
90 
91  if (!namespaceLookup.TryGetValue(name, out ns))
92  {
93  ns = new CodeNamespace(CodeGenUtil.Instance.Mangle(name));
94  foreach (CodeNamespaceImport nci in CodeGenUtil.Instance.NamespaceImports)
95  ns.Imports.Add(nci);
96 
97  CompileUnit.Namespaces.Add(ns);
98  namespaceLookup.Add(name, ns);
99  }
100  return ns;
101  }
102 
107  public virtual CodeCompileUnit GenerateCode()
108  {
109  CompileUnit = new CodeCompileUnit();
110 
111  processSchemas();
113 
114  return CompileUnit;
115  }
116 
120  protected virtual void processSchemas()
121  {
122  foreach (Schema schema in this.Schemas)
123  {
124  SchemaNames names = generateNames(schema);
125  foreach (KeyValuePair<SchemaName, NamedSchema> sn in names)
126  {
127  switch (sn.Value.Tag)
128  {
129  case Schema.Type.Enumeration: processEnum(sn.Value); break;
130  case Schema.Type.Fixed: processFixed(sn.Value); break;
131  case Schema.Type.Record: processRecord(sn.Value); break;
132  case Schema.Type.Error: processRecord(sn.Value); break;
133  default:
134  throw new CodeGenException("Names in schema should only be of type NamedSchema, type found " + sn.Value.Tag);
135  }
136  }
137  }
138  }
139 
143  protected virtual void processProtocols()
144  {
145  foreach (Protocol protocol in Protocols)
146  {
147  SchemaNames names = generateNames(protocol);
148  foreach (KeyValuePair<SchemaName, NamedSchema> sn in names)
149  {
150  switch (sn.Value.Tag)
151  {
152  case Schema.Type.Enumeration: processEnum(sn.Value); break;
153  case Schema.Type.Fixed: processFixed(sn.Value); break;
154  case Schema.Type.Record: processRecord(sn.Value); break;
155  case Schema.Type.Error: processRecord(sn.Value); break;
156  default:
157  throw new CodeGenException("Names in protocol should only be of type NamedSchema, type found " + sn.Value.Tag);
158  }
159  }
160 
161  processInterface(protocol);
162  }
163  }
164 
170  protected virtual SchemaNames generateNames(Protocol protocol)
171  {
172  var names = new SchemaNames();
173  foreach (Schema schema in protocol.Types)
174  addName(schema, names);
175  return names;
176  }
177 
183  protected virtual SchemaNames generateNames(Schema schema)
184  {
185  var names = new SchemaNames();
186  addName(schema, names);
187  return names;
188  }
189 
195  protected virtual void addName(Schema schema, SchemaNames names)
196  {
197  NamedSchema ns = schema as NamedSchema;
198  if (null != ns) if (names.Contains(ns.SchemaName)) return;
199 
200  switch (schema.Tag)
201  {
202  case Schema.Type.Null:
203  case Schema.Type.Boolean:
204  case Schema.Type.Int:
205  case Schema.Type.Long:
206  case Schema.Type.Float:
207  case Schema.Type.Double:
208  case Schema.Type.Bytes:
209  case Schema.Type.String:
210  break;
211 
212  case Schema.Type.Enumeration:
213  case Schema.Type.Fixed:
214  names.Add(ns);
215  break;
216 
217  case Schema.Type.Record:
218  case Schema.Type.Error:
219  var rs = schema as RecordSchema;
220  names.Add(rs);
221  foreach (Field field in rs.Fields)
222  addName(field.Schema, names);
223  break;
224 
225  case Schema.Type.Array:
226  var asc = schema as ArraySchema;
227  addName(asc.ItemSchema, names);
228  break;
229 
230  case Schema.Type.Map:
231  var ms = schema as MapSchema;
232  addName(ms.ValueSchema, names);
233  break;
234 
235  case Schema.Type.Union:
236  var us = schema as UnionSchema;
237  foreach (Schema usc in us.Schemas)
238  addName(usc, names);
239  break;
240 
241  default:
242  throw new CodeGenException("Unable to add name for " + schema.Name + " type " + schema.Tag);
243  }
244  }
245 
251  protected virtual void processFixed(Schema schema)
252  {
253  FixedSchema fixedSchema = schema as FixedSchema;
254  if (null == fixedSchema) throw new CodeGenException("Unable to cast schema into a fixed");
255 
256  CodeTypeDeclaration ctd = new CodeTypeDeclaration();
257  ctd.Name = CodeGenUtil.Instance.Mangle(fixedSchema.Name);
258  ctd.IsClass = true;
259  ctd.IsPartial = true;
260  ctd.Attributes = MemberAttributes.Public;
261  ctd.BaseTypes.Add("SpecificFixed");
262 
263  // create static schema field
264  createSchemaField(schema, ctd, true);
265 
266  // Add Size field
267  string sizefname = "fixedSize";
268  var ctrfield = new CodeTypeReference(typeof(uint));
269  var codeField = new CodeMemberField(ctrfield, sizefname);
270  codeField.Attributes = MemberAttributes.Private | MemberAttributes.Static;
271  codeField.InitExpression = new CodePrimitiveExpression(fixedSchema.Size);
272  ctd.Members.Add(codeField);
273 
274  // Add Size property
275  var fieldRef = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), sizefname);
276  var property = new CodeMemberProperty();
277  property.Attributes = MemberAttributes.Public | MemberAttributes.Static;
278  property.Name = "FixedSize";
279  property.Type = ctrfield;
280  property.GetStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression(schema.Name + "." + sizefname)));
281  ctd.Members.Add(property);
282 
283  // create constructor to initiate base class SpecificFixed
284  CodeConstructor cc = new CodeConstructor();
285  cc.Attributes = MemberAttributes.Public;
286  cc.BaseConstructorArgs.Add(new CodeVariableReferenceExpression(sizefname));
287  ctd.Members.Add(cc);
288 
289  string nspace = fixedSchema.Namespace;
290  if (string.IsNullOrEmpty(nspace))
291  throw new CodeGenException("Namespace required for enum schema " + fixedSchema.Name);
292  CodeNamespace codens = addNamespace(nspace);
293  codens.Types.Add(ctd);
294  }
295 
301  protected virtual void processEnum(Schema schema)
302  {
303  EnumSchema enumschema = schema as EnumSchema;
304  if (null == enumschema) throw new CodeGenException("Unable to cast schema into an enum");
305 
306  CodeTypeDeclaration ctd = new CodeTypeDeclaration(CodeGenUtil.Instance.Mangle(enumschema.Name));
307  ctd.IsEnum = true;
308  ctd.Attributes = MemberAttributes.Public;
309 
310  foreach (string symbol in enumschema.Symbols)
311  {
312  if (CodeGenUtil.Instance.ReservedKeywords.Contains(symbol))
313  throw new CodeGenException("Enum symbol " + symbol + " is a C# reserved keyword");
314  CodeMemberField field = new CodeMemberField(typeof(int), symbol);
315  ctd.Members.Add(field);
316  }
317 
318  string nspace = enumschema.Namespace;
319  if (string.IsNullOrEmpty(nspace))
320  throw new CodeGenException("Namespace required for enum schema " + enumschema.Name);
321  CodeNamespace codens = addNamespace(nspace);
322 
323  codens.Types.Add(ctd);
324  }
325 
326  protected virtual void processInterface(Protocol protocol)
327  {
328  // Create abstract class
329  string protocolNameMangled = CodeGenUtil.Instance.Mangle(protocol.Name);
330 
331  var ctd = new CodeTypeDeclaration(protocolNameMangled);
332  ctd.TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public;
333  ctd.IsClass = true;
334  ctd.BaseTypes.Add("Avro.Specific.ISpecificProtocol");
335 
336  AddProtocolDocumentation(protocol, ctd);
337 
338  // Add static protocol field.
339  var protocolField = new CodeMemberField();
340  protocolField.Attributes = MemberAttributes.Private | MemberAttributes.Static | MemberAttributes.Final;
341  protocolField.Name = "protocol";
342  protocolField.Type = new CodeTypeReference("readonly Avro.Protocol");
343 
344  var cpe = new CodePrimitiveExpression(protocol.ToString());
345  var cmie = new CodeMethodInvokeExpression(
346  new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(Protocol)), "Parse"),
347  new CodeExpression[] { cpe });
348 
349  protocolField.InitExpression = cmie;
350 
351  ctd.Members.Add(protocolField);
352 
353  // Add overridden Protocol method.
354  var property = new CodeMemberProperty();
355  property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
356  property.Name = "Protocol";
357  property.Type = new CodeTypeReference("Avro.Protocol");
358  property.HasGet = true;
359 
360 
361  property.GetStatements.Add(new CodeTypeReferenceExpression("return protocol"));
362  ctd.Members.Add(property);
363 
364  //var requestMethod = CreateRequestMethod();
365  //ctd.Members.Add(requestMethod);
366 
367  var requestMethod = CreateRequestMethod();
368  //requestMethod.Attributes |= MemberAttributes.Override;
369  var builder = new StringBuilder();
370 
371  if (protocol.Messages.Count > 0)
372  {
373  builder.Append("switch(messageName)\n\t\t\t{");
374 
375  foreach (var a in protocol.Messages)
376  {
377  builder.Append("\n\t\t\t\tcase \"").Append(a.Key).Append("\":\n");
378 
379  bool unused = false;
380  string type = getType(a.Value.Response, false, ref unused);
381 
382  builder.Append("\t\t\t\trequestor.Request<")
383  .Append(type)
384  .Append(">(messageName, args, callback);\n");
385  builder.Append("\t\t\t\tbreak;\n");
386  }
387 
388  builder.Append("\t\t\t}");
389  }
390  var cseGet = new CodeSnippetExpression(builder.ToString());
391 
392  requestMethod.Statements.Add(cseGet);
393  ctd.Members.Add(requestMethod);
394 
395  AddMethods(protocol, false, ctd);
396 
397  string nspace = protocol.Namespace;
398  if (string.IsNullOrEmpty(nspace))
399  throw new CodeGenException("Namespace required for enum schema " + nspace);
400  CodeNamespace codens = addNamespace(nspace);
401 
402  codens.Types.Add(ctd);
403 
404  // Create callback abstract class
405  ctd = new CodeTypeDeclaration(protocolNameMangled + "Callback");
406  ctd.TypeAttributes = TypeAttributes.Abstract | TypeAttributes.Public;
407  ctd.IsClass = true;
408  ctd.BaseTypes.Add(protocolNameMangled);
409 
410  // Need to override
411 
412 
413 
414  AddProtocolDocumentation(protocol, ctd);
415 
416  AddMethods(protocol, true, ctd);
417 
418  codens.Types.Add(ctd);
419  }
420 
421  private static CodeMemberMethod CreateRequestMethod()
422  {
423  var requestMethod = new CodeMemberMethod();
424  requestMethod.Attributes = MemberAttributes.Public | MemberAttributes.Final;
425  requestMethod.Name = "Request";
426  requestMethod.ReturnType = new CodeTypeReference(typeof (void));
427  {
428  var requestor = new CodeParameterDeclarationExpression(typeof (Avro.Specific.ICallbackRequestor),
429  "requestor");
430  requestMethod.Parameters.Add(requestor);
431 
432  var messageName = new CodeParameterDeclarationExpression(typeof (string), "messageName");
433  requestMethod.Parameters.Add(messageName);
434 
435  var args = new CodeParameterDeclarationExpression(typeof (object[]), "args");
436  requestMethod.Parameters.Add(args);
437 
438  var callback = new CodeParameterDeclarationExpression(typeof (object), "callback");
439  requestMethod.Parameters.Add(callback);
440  }
441  return requestMethod;
442  }
443 
444  private static void AddMethods(Protocol protocol, bool generateCallback, CodeTypeDeclaration ctd)
445  {
446  foreach (var e in protocol.Messages)
447  {
448  var name = e.Key;
449  var message = e.Value;
450  var response = message.Response;
451 
452  if (generateCallback && message.Oneway.GetValueOrDefault())
453  continue;
454 
455  var messageMember = new CodeMemberMethod();
456  messageMember.Name = CodeGenUtil.Instance.Mangle(name);
457  messageMember.Attributes = MemberAttributes.Public | MemberAttributes.Abstract;
458 
459  if (message.Doc!= null && message.Doc.Trim() != string.Empty)
460  messageMember.Comments.Add(new CodeCommentStatement(message.Doc));
461 
462  if (message.Oneway.GetValueOrDefault() || generateCallback)
463  {
464  messageMember.ReturnType = new CodeTypeReference(typeof (void));
465  }
466  else
467  {
468  bool ignored = false;
469  string type = getType(response, false, ref ignored);
470 
471  messageMember.ReturnType = new CodeTypeReference(type);
472  }
473 
474  foreach (Field field in message.Request.Fields)
475  {
476  bool ignored = false;
477  string type = getType(field.Schema, false, ref ignored);
478 
479  string fieldName = CodeGenUtil.Instance.Mangle(field.Name);
480  var parameter = new CodeParameterDeclarationExpression(type, fieldName);
481  messageMember.Parameters.Add(parameter);
482  }
483 
484  if (generateCallback)
485  {
486  bool unused = false;
487  var type = getType(response, false, ref unused);
488  var parameter = new CodeParameterDeclarationExpression("Avro.IO.ICallback<" + type + ">",
489  "callback");
490  messageMember.Parameters.Add(parameter);
491  }
492 
493 
494  ctd.Members.Add(messageMember);
495  }
496  }
497 
498  private void AddProtocolDocumentation(Protocol protocol, CodeTypeDeclaration ctd)
499  {
500  // Add interface documentation
501  if (protocol.Doc != null && protocol.Doc.Trim() != string.Empty)
502  {
503  var interfaceDoc = createDocComment(protocol.Doc);
504  if (interfaceDoc != null)
505  ctd.Comments.Add(interfaceDoc);
506  }
507  }
508 
515  protected virtual CodeTypeDeclaration processRecord(Schema schema)
516  {
517  RecordSchema recordSchema = schema as RecordSchema;
518  if (null == recordSchema) throw new CodeGenException("Unable to cast schema into a record");
519 
520  bool isError = recordSchema.Tag == Schema.Type.Error;
521 
522  // declare the class
523  var ctd = new CodeTypeDeclaration(CodeGenUtil.Instance.Mangle(recordSchema.Name));
524  ctd.BaseTypes.Add(isError ? "SpecificException" : "ISpecificRecord");
525 
526  ctd.Attributes = MemberAttributes.Public;
527  ctd.IsClass = true;
528  ctd.IsPartial = true;
529 
530  createSchemaField(schema, ctd, isError);
531 
532  // declare Get() to be used by the Writer classes
533  var cmmGet = new CodeMemberMethod();
534  cmmGet.Name = "Get";
535  cmmGet.Attributes = MemberAttributes.Public;
536  cmmGet.ReturnType = new CodeTypeReference("System.Object");
537  cmmGet.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "fieldPos"));
538  StringBuilder getFieldStmt = new StringBuilder("switch (fieldPos)\n\t\t\t{\n");
539 
540  // declare Put() to be used by the Reader classes
541  var cmmPut = new CodeMemberMethod();
542  cmmPut.Name = "Put";
543  cmmPut.Attributes = MemberAttributes.Public;
544  cmmPut.ReturnType = new CodeTypeReference(typeof(void));
545  cmmPut.Parameters.Add(new CodeParameterDeclarationExpression(typeof(int), "fieldPos"));
546  cmmPut.Parameters.Add(new CodeParameterDeclarationExpression("System.Object", "fieldValue"));
547  var putFieldStmt = new StringBuilder("switch (fieldPos)\n\t\t\t{\n");
548 
549  if (isError)
550  {
551  cmmGet.Attributes |= MemberAttributes.Override;
552  cmmPut.Attributes |= MemberAttributes.Override;
553  }
554 
555  foreach (Field field in recordSchema.Fields)
556  {
557  // Determine type of field
558  bool nullibleEnum = false;
559  string baseType = getType(field.Schema, false, ref nullibleEnum);
560  var ctrfield = new CodeTypeReference(baseType);
561 
562  // Create field
563  string privFieldName = string.Concat("_", field.Name);
564  var codeField = new CodeMemberField(ctrfield, privFieldName);
565  codeField.Attributes = MemberAttributes.Private;
566 
567  // Process field documentation if it exist and add to the field
568  CodeCommentStatement propertyComment = null;
569  if (!string.IsNullOrEmpty(field.Documentation))
570  {
571  propertyComment = createDocComment(field.Documentation);
572  if (null != propertyComment)
573  codeField.Comments.Add(propertyComment);
574  }
575 
576  // Add field to class
577  ctd.Members.Add(codeField);
578 
579  // Create reference to the field - this.fieldname
580  var fieldRef = new CodeFieldReferenceExpression(new CodeThisReferenceExpression(), privFieldName);
581  var mangledName = CodeGenUtil.Instance.Mangle(field.Name);
582 
583  // Create field property with get and set methods
584  var property = new CodeMemberProperty();
585  property.Attributes = MemberAttributes.Public | MemberAttributes.Final;
586  property.Name = mangledName;
587  property.Type = ctrfield;
588  property.GetStatements.Add(new CodeMethodReturnStatement(fieldRef));
589  property.SetStatements.Add(new CodeAssignStatement(fieldRef, new CodePropertySetValueReferenceExpression()));
590  if (null != propertyComment)
591  property.Comments.Add(propertyComment);
592 
593  // Add field property to class
594  ctd.Members.Add(property);
595 
596  // add to Get()
597  getFieldStmt.Append("\t\t\tcase ");
598  getFieldStmt.Append(field.Pos);
599  getFieldStmt.Append(": return this.");
600  getFieldStmt.Append(mangledName);
601  getFieldStmt.Append(";\n");
602 
603  // add to Put()
604  putFieldStmt.Append("\t\t\tcase ");
605  putFieldStmt.Append(field.Pos);
606  putFieldStmt.Append(": this.");
607  putFieldStmt.Append(mangledName);
608 
609  if (nullibleEnum)
610  {
611  putFieldStmt.Append(" = fieldValue == null ? (");
612  putFieldStmt.Append(baseType);
613  putFieldStmt.Append(")null : (");
614 
615  string type = baseType.Remove(0, 16); // remove System.Nullable<
616  type = type.Remove(type.Length - 1); // remove >
617 
618  putFieldStmt.Append(type);
619  putFieldStmt.Append(")fieldValue; break;\n");
620  }
621  else
622  {
623  putFieldStmt.Append(" = (");
624  putFieldStmt.Append(baseType);
625  putFieldStmt.Append(")fieldValue; break;\n");
626  }
627  }
628 
629  // end switch block for Get()
630  getFieldStmt.Append("\t\t\tdefault: throw new AvroRuntimeException(\"Bad index \" + fieldPos + \" in Get()\");\n\t\t\t}");
631  var cseGet = new CodeSnippetExpression(getFieldStmt.ToString());
632  cmmGet.Statements.Add(cseGet);
633  ctd.Members.Add(cmmGet);
634 
635  // end switch block for Put()
636  putFieldStmt.Append("\t\t\tdefault: throw new AvroRuntimeException(\"Bad index \" + fieldPos + \" in Put()\");\n\t\t\t}");
637  var csePut = new CodeSnippetExpression(putFieldStmt.ToString());
638  cmmPut.Statements.Add(csePut);
639  ctd.Members.Add(cmmPut);
640 
641  string nspace = recordSchema.Namespace;
642  if (string.IsNullOrEmpty(nspace))
643  throw new CodeGenException("Namespace required for record schema " + recordSchema.Name);
644  CodeNamespace codens = addNamespace(nspace);
645 
646  codens.Types.Add(ctd);
647 
648  return ctd;
649  }
650 
657  internal static string getType(Schema schema, bool nullible, ref bool nullibleEnum)
658  {
659  switch (schema.Tag)
660  {
661  case Schema.Type.Null:
662  return "System.Object";
663  case Schema.Type.Boolean:
664  if (nullible) return "System.Nullable<bool>";
665  else return typeof(bool).ToString();
666  case Schema.Type.Int:
667  if (nullible) return "System.Nullable<int>";
668  else return typeof(int).ToString();
669  case Schema.Type.Long:
670  if (nullible) return "System.Nullable<long>";
671  else return typeof(long).ToString();
672  case Schema.Type.Float:
673  if (nullible) return "System.Nullable<float>";
674  else return typeof(float).ToString();
675  case Schema.Type.Double:
676  if (nullible) return "System.Nullable<double>";
677  else return typeof(double).ToString();
678 
679  case Schema.Type.Bytes:
680  return typeof(byte[]).ToString();
681  case Schema.Type.String:
682  return typeof(string).ToString();
683 
684  case Schema.Type.Enumeration:
685  var namedSchema = schema as NamedSchema;
686  if (null == namedSchema)
687  throw new CodeGenException("Unable to cast schema into a named schema");
688  if (nullible)
689  {
690  nullibleEnum = true;
691  return "System.Nullable<" + CodeGenUtil.Instance.Mangle(namedSchema.Fullname) + ">";
692  }
693  else return CodeGenUtil.Instance.Mangle(namedSchema.Fullname);
694 
695  case Schema.Type.Fixed:
696  case Schema.Type.Record:
697  case Schema.Type.Error:
698  namedSchema = schema as NamedSchema;
699  if (null == namedSchema)
700  throw new CodeGenException("Unable to cast schema into a named schema");
701  return CodeGenUtil.Instance.Mangle(namedSchema.Fullname);
702 
703  case Schema.Type.Array:
704  var arraySchema = schema as ArraySchema;
705  if (null == arraySchema)
706  throw new CodeGenException("Unable to cast schema into an array schema");
707 
708  return "IList<" + getType(arraySchema.ItemSchema, false, ref nullibleEnum) + ">";
709 
710  case Schema.Type.Map:
711  var mapSchema = schema as MapSchema;
712  if (null == mapSchema)
713  throw new CodeGenException("Unable to cast schema into a map schema");
714  return "IDictionary<string," + getType(mapSchema.ValueSchema, false, ref nullibleEnum) + ">";
715 
716  case Schema.Type.Union:
717  var unionSchema = schema as UnionSchema;
718  if (null == unionSchema)
719  throw new CodeGenException("Unable to cast schema into a union schema");
720  Schema nullibleType = getNullableType(unionSchema);
721  if (null == nullibleType)
722  return CodeGenUtil.Object;
723  else
724  return getType(nullibleType, true, ref nullibleEnum);
725  }
726  throw new CodeGenException("Unable to generate CodeTypeReference for " + schema.Name + " type " + schema.Tag);
727  }
728 
734  public static Schema getNullableType(UnionSchema schema)
735  {
736  Schema ret = null;
737  if (schema.Count == 2)
738  {
739  bool nullable = false;
740  foreach (Schema childSchema in schema.Schemas)
741  {
742  if (childSchema.Tag == Schema.Type.Null)
743  nullable = true;
744  else
745  ret = childSchema;
746  }
747  if (!nullable)
748  ret = null;
749  }
750  return ret;
751  }
752 
758  protected virtual void createSchemaField(Schema schema, CodeTypeDeclaration ctd, bool overrideFlag)
759  {
760  // create schema field
761  var ctrfield = new CodeTypeReference("Schema");
762  string schemaFname = "_SCHEMA";
763  var codeField = new CodeMemberField(ctrfield, schemaFname);
764  codeField.Attributes = MemberAttributes.Public | MemberAttributes.Static;
765  // create function call Schema.Parse(json)
766  var cpe = new CodePrimitiveExpression(schema.ToString());
767  var cmie = new CodeMethodInvokeExpression(
768  new CodeMethodReferenceExpression(new CodeTypeReferenceExpression(typeof(Schema)), "Parse"),
769  new CodeExpression[] { cpe });
770  codeField.InitExpression = cmie;
771  ctd.Members.Add(codeField);
772 
773  // create property to get static schema field
774  var property = new CodeMemberProperty();
775  property.Attributes = MemberAttributes.Public;
776  if (overrideFlag) property.Attributes |= MemberAttributes.Override;
777  property.Name = "Schema";
778  property.Type = ctrfield;
779 
780  property.GetStatements.Add(new CodeMethodReturnStatement(new CodeTypeReferenceExpression(ctd.Name + "." + schemaFname)));
781  ctd.Members.Add(property);
782  }
783 
789  protected virtual CodeCommentStatement createDocComment(string comment)
790  {
791  string text = string.Format("<summary>\r\n {0}\r\n </summary>", comment);
792  return new CodeCommentStatement(text, true);
793  }
794 
799  public virtual void WriteCompileUnit(string outputFile)
800  {
801  var cscp = new CSharpCodeProvider();
802 
803  var opts = new CodeGeneratorOptions();
804  opts.BracingStyle = "C";
805  opts.IndentString = "\t";
806  opts.BlankLinesBetweenMembers = false;
807 
808  using (var outfile = new StreamWriter(outputFile))
809  {
810  cscp.GenerateCodeFromCompileUnit(CompileUnit, outfile, opts);
811  }
812  }
813 
818  public virtual void WriteTypes(string outputdir)
819  {
820  var cscp = new CSharpCodeProvider();
821 
822  var opts = new CodeGeneratorOptions();
823  opts.BracingStyle = "C";
824  opts.IndentString = "\t";
825  opts.BlankLinesBetweenMembers = false;
826 
827  CodeNamespaceCollection nsc = CompileUnit.Namespaces;
828  for (int i = 0; i < nsc.Count; i++)
829  {
830  var ns = nsc[i];
831 
832  string dir = outputdir + "\\" + CodeGenUtil.Instance.UnMangle(ns.Name).Replace('.', '\\');
833  Directory.CreateDirectory(dir);
834 
835  var new_ns = new CodeNamespace(ns.Name);
836  new_ns.Comments.Add(CodeGenUtil.Instance.FileComment);
837  foreach (CodeNamespaceImport nci in CodeGenUtil.Instance.NamespaceImports)
838  new_ns.Imports.Add(nci);
839 
840  var types = ns.Types;
841  for (int j = 0; j < types.Count; j++)
842  {
843  var ctd = types[j];
844  string file = dir + "\\" + CodeGenUtil.Instance.UnMangle(ctd.Name) + ".cs";
845  using (var writer = new StreamWriter(file, false))
846  {
847  new_ns.Types.Add(ctd);
848  cscp.GenerateCodeFromNamespace(new_ns, writer, opts);
849  new_ns.Types.Remove(ctd);
850  }
851  }
852  }
853  }
854  }
855 }
virtual CodeNamespace addNamespace(string name)
Adds a namespace object for the given name into the dictionary if it doesn't exist yet
Definition: CodeGen.cs:84
Class for record schemas
Definition: RecordSchema.cs:31
virtual SchemaNames generateNames(Protocol protocol)
Generate list of named schemas from given protocol
Definition: CodeGen.cs:170
Schema Schema
Field type's schema
Definition: Field.cs:75
Class for fields defined in a record
Definition: Field.cs:30
virtual CodeCommentStatement createDocComment(string comment)
Creates an XML documentation for the given comment
Definition: CodeGen.cs:789
Class for enum type schemas
Definition: EnumSchema.cs:28
virtual void createSchemaField(Schema schema, CodeTypeDeclaration ctd, bool overrideFlag)
Creates the static schema field for class types
Definition: CodeGen.cs:758
IList< Schema > Types
List of schemas objects representing the different schemas defined under the 'types' attribute
Definition: Protocol.cs:47
CodeGen()
Default constructor
Definition: CodeGen.cs:55
virtual CodeTypeDeclaration processRecord(Schema schema)
Creates a class declaration
Definition: CodeGen.cs:515
virtual SchemaNames generateNames(Schema schema)
Generate list of named schemas from given schema
Definition: CodeGen.cs:183
int Pos
Position of the field within its record.
Definition: Field.cs:55
Base class for all schema types
Definition: Schema.cs:29
bool Contains(SchemaName name)
Checks if given name is in the map
Definition: SchemaName.cs:166
string Name
Name of the protocol
Definition: Protocol.cs:32
Class for union schemas
Definition: UnionSchema.cs:29
CodeNamespaceImport [] NamespaceImports
Definition: CodeGenUtil.cs:34
override string Name
Name of the schema
Definition: NamedSchema.cs:40
readonly string Name
Name of the field.
Definition: Field.cs:45
IList< Schema > Schemas
List of schemas in the union
Definition: UnionSchema.cs:34
A singleton class containing data used by codegen
Definition: CodeGenUtil.cs:29
Class for fixed schemas
Definition: FixedSchema.cs:28
CodeCompileUnit CompileUnit
Object that contains all the generated types
Definition: CodeGen.cs:35
IList< Protocol > Protocols
List of protocols to generate code for
Definition: CodeGen.cs:45
virtual void processInterface(Protocol protocol)
Definition: CodeGen.cs:326
Type
Enum for schema types
Definition: Schema.cs:34
int Size
Fixed size for the bytes
Definition: FixedSchema.cs:33
Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements.
CodeCommentStatement FileComment
Definition: CodeGenUtil.cs:35
override string ToString()
Returns the canonical JSON representation of this schema.
Definition: Schema.cs:191
static Schema getNullableType(UnionSchema schema)
Gets the schema of a union with null
Definition: CodeGen.cs:734
virtual void AddSchema(Schema schema)
Adds a schema object to generate code for
Definition: CodeGen.cs:74
virtual void processFixed(Schema schema)
Creates a class declaration for fixed schema
Definition: CodeGen.cs:251
string Namespace
Namespace of the schema
Definition: NamedSchema.cs:48
Class for array type schemas
Definition: ArraySchema.cs:27
A class that contains a list of named schemas.
Definition: SchemaName.cs:146
string UnMangle(string name)
Remove all the @
Definition: CodeGenUtil.cs:96
virtual void processProtocols()
Generates code for the protocol objects
Definition: CodeGen.cs:143
Class for map schemas
Definition: MapSchema.cs:28
IList< Schema > Schemas
List of schemas to generate code for
Definition: CodeGen.cs:40
override string ToString()
Writes Protocol in JSON format
Definition: Protocol.cs:158
virtual void addName(Schema schema, SchemaNames names)
Recursively search the given schema for named schemas and adds them to the given container
Definition: CodeGen.cs:195
bool Add(SchemaName name, NamedSchema schema)
Adds a schema name to the map if it doesn't exist yet
Definition: SchemaName.cs:179
Dictionary< string, CodeNamespace > namespaceLookup
List of generated namespaces
Definition: CodeGen.cs:50
static CodeGenUtil Instance
Definition: CodeGenUtil.cs:32
abstract string Name
The name of this schema.
Definition: Schema.cs:77
IDictionary< string, Message > Messages
List of message objects representing the different schemas defined under the 'messages' attribute
Definition: Protocol.cs:52
string Documentation
Documentation for the field, if any.
Definition: Field.cs:60
HashSet< string > ReservedKeywords
Definition: CodeGenUtil.cs:36
int Count
Count of schemas in the union
Definition: UnionSchema.cs:39
virtual CodeCompileUnit GenerateCode()
Generates code for the given protocol and schema objects
Definition: CodeGen.cs:107
virtual void AddProtocol(Protocol protocol)
Adds a protocol object to generate code for
Definition: CodeGen.cs:65
virtual void processEnum(Schema schema)
Creates an enum declaration
Definition: CodeGen.cs:301
Type Tag
Schema type property
Definition: Schema.cs:56
virtual void WriteCompileUnit(string outputFile)
Writes the generated compile unit into one file
Definition: CodeGen.cs:799
string Mangle(string name)
Append @ to all reserved keywords that appear on the given name
Definition: CodeGenUtil.cs:76
string Namespace
Namespace of the protocol
Definition: Protocol.cs:37
virtual void WriteTypes(string outputdir)
Writes each types in each namespaces into individual files
Definition: CodeGen.cs:818
Base class for all named schemas: fixed, enum, record
Definition: NamedSchema.cs:29
virtual void processSchemas()
Generates code for the schema objects
Definition: CodeGen.cs:120
SchemaName SchemaName
Name of the schema, contains name, namespace and enclosing namespace
Definition: NamedSchema.cs:34