@@ -12,12 +12,12 @@ namespace ConfigGen
1212 internal class MappingConfiguration
1313 {
1414 /// <summary>
15- /// librdkafka _RK_C_S2I properties are automatically interpreted as enums, however
16- /// _RK_C_STR properties with discrete set of allowed values are not. Enum values for
15+ /// librdkafka _RK_C_S2I properties are automatically interpreted as enums, however
16+ /// _RK_C_STR properties with discrete set of allowed values are not. Enum values for
1717 /// these property types are specified here.
1818 /// </summary>
1919 /// <remarks>
20- /// sasl.mechanisms is an awkward case because the values contain '-' characters (and
20+ /// sasl.mechanisms is an awkward case because the values contain '-' characters (and
2121 /// there are other values that contain the '_' character, so can't 1:1 map with this).
2222 /// This type is defined by hand later.
2323 /// </remarks>
@@ -31,7 +31,7 @@ internal class MappingConfiguration
3131 /// A function that filters out properties from the librdkafka list that should
3232 /// not be automatically extracted.
3333 /// </summary>
34- internal static List < PropertySpecification > RemoveLegacyOrNotRelevant ( List < PropertySpecification > props )
34+ internal static List < PropertySpecification > RemoveLegacyOrNotRelevant ( List < PropertySpecification > props )
3535 => props . Where ( p => {
3636 // handled as a special case.
3737 if ( p . Name == "sasl.mechanisms" ) { return false ; }
@@ -204,7 +204,7 @@ public Acks? Acks
204204
205205 }
206206
207-
207+
208208 class PropertySpecification : IComparable
209209 {
210210 public PropertySpecification ( ) { }
@@ -370,7 +370,7 @@ static string createClassFooter()
370370 static string createEnums ( List < PropertySpecification > props )
371371 {
372372 var codeText = "" ;
373- for ( int j = 0 ; j < props . Count ( ) ; ++ j )
373+ for ( int j = 0 ; j < props . Count ( ) ; ++ j )
374374 {
375375 var prop = props [ j ] ;
376376 List < string > vs = null ;
@@ -393,14 +393,14 @@ static string createEnums(List<PropertySpecification> props)
393393 codeText += $ " /// </summary>\n ";
394394 codeText += $ " public enum { ConfigNameToDotnetName ( prop . Name ) } \n ";
395395 codeText += $ " {{\n ";
396- for ( int i = 0 ; i < vs . Count ; ++ i )
396+ for ( int i = 0 ; i < vs . Count ; ++ i )
397397 {
398398 var v = vs [ i ] ;
399399 var nm = EnumNameToDotnetName ( v ) ;
400400 codeText += $ " /// <summary>\n ";
401401 codeText += $ " /// { nm } \n ";
402402 codeText += $ " /// </summary>\n ";
403- codeText += $ " { nm } { ( i == vs . Count - 1 ? "" : ",\n " ) } \n ";
403+ codeText += $ " { nm } { ( i == vs . Count - 1 ? "" : ",\n " ) } \n ";
404404 }
405405 codeText += $ " }}\n ";
406406 }
@@ -418,35 +418,45 @@ static string createClassHeader(string name, string docs, bool derive)
418418 return codeText ;
419419 }
420420
421- static string createConsumerSpecific ( )
421+ static string createClassConstructors ( string name )
422422 {
423- return
424- @" /// <summary>
425- /// Initialize a new empty <see cref=""ConsumerConfig "" /> instance.
423+ var codeText = $@ "
424+ /// <summary>
425+ /// Initialize a new empty <see cref=""{ name } "" /> instance.
426426 /// </summary>
427- public ConsumerConfig () { }
427+ public { name } () : base() {{ } }
428428
429429 /// <summary>
430- /// Initialize a new <see cref=""ConsumerConfig "" /> instance based on
430+ /// Initialize a new <see cref=""{ name } "" /> instance wrapping
431431 /// an existing <see cref=""ClientConfig"" /> instance.
432+ /// This will change the values ""in-place"" i.e. operations on this class WILL modify the provided collection
432433 /// </summary>
433- public ConsumerConfig (ClientConfig config) { this.properties = new Dictionary<string, string> (config.ToDictionary(a => a.Key, a => a.Value)); }
434+ public { name } (ClientConfig config) : base (config) {{ } }
434435
435436 /// <summary>
436- /// Initialize a new <see cref=""ConsumerConfig "" /> instance based on
437+ /// Initialize a new <see cref=""{ name } "" /> instance wrapping
437438 /// an existing key/value pair collection.
439+ /// This will change the values ""in-place"" i.e. operations on this class WILL modify the provided collection
438440 /// </summary>
439- public ConsumerConfig(IEnumerable<KeyValuePair<string, string>> config) { this.properties = new Dictionary<string, string>(config.ToDictionary(a => a.Key, a => a.Value)); }
441+ public { name } (IDictionary<string, string> config) : base(config) {{ }}
442+ " ;
443+ return codeText ;
444+ }
440445
446+ static string createConsumerSpecific ( )
447+ {
448+ return
449+ createClassConstructors ( "ConsumerConfig" ) +
450+ @"
441451 /// <summary>
442452 /// A comma separated list of fields that may be optionally set
443453 /// in <see cref=""Confluent.Kafka.ConsumeResult{TKey,TValue}"" />
444454 /// objects returned by the
445455 /// <see cref=""Confluent.Kafka.Consumer{TKey,TValue}.Consume(System.TimeSpan)"" />
446- /// method. Disabling fields that you do not require will improve
456+ /// method. Disabling fields that you do not require will improve
447457 /// throughput and reduce memory consumption. Allowed values:
448458 /// headers, timestamp, topic, all, none
449- ///
459+ ///
450460 /// default: all
451461 /// importance: low
452462 /// </summary>
@@ -458,29 +468,14 @@ public ConsumerConfig() {}
458468 static string createProducerSpecific ( )
459469 {
460470 return
461- @" /// <summary>
462- /// Initialize a new empty <see cref=""ProducerConfig"" /> instance.
463- /// </summary>
464- public ProducerConfig() {}
465-
466- /// <summary>
467- /// Initialize a new <see cref=""ProducerConfig"" /> instance based on
468- /// an existing <see cref=""ClientConfig"" /> instance.
469- /// </summary>
470- public ProducerConfig(ClientConfig config) { this.properties = new Dictionary<string, string>(config.ToDictionary(a => a.Key, a => a.Value)); }
471-
472- /// <summary>
473- /// Initialize a new <see cref=""ProducerConfig"" /> instance based on
474- /// an existing key/value pair collection.
475- /// </summary>
476- public ProducerConfig(IEnumerable<KeyValuePair<string, string>> config) { this.properties = new Dictionary<string, string>(config.ToDictionary(a => a.Key, a => a.Value)); }
477-
471+ createClassConstructors ( "ProducerConfig" ) +
472+ @"
478473 /// <summary>
479- /// Specifies whether or not the producer should start a background poll
474+ /// Specifies whether or not the producer should start a background poll
480475 /// thread to receive delivery reports and event notifications. Generally,
481- /// this should be set to true. If set to false, you will need to call
476+ /// this should be set to true. If set to false, you will need to call
482477 /// the Poll function manually.
483- ///
478+ ///
484479 /// default: true
485480 /// importance: low
486481 /// </summary>
@@ -490,7 +485,7 @@ public ProducerConfig() {}
490485 /// Specifies whether to enable notification of delivery reports. Typically
491486 /// you should set this parameter to true. Set it to false for ""fire and
492487 /// forget"" semantics and a small boost in performance.
493- ///
488+ ///
494489 /// default: true
495490 /// importance: low
496491 /// </summary>
@@ -501,7 +496,7 @@ public ProducerConfig() {}
501496 /// reports. Disabling delivery report fields that you do not require will
502497 /// improve maximum throughput and reduce memory usage. Allowed values:
503498 /// key, value, timestamp, headers, all, none.
504- ///
499+ ///
505500 /// default: all
506501 /// importance: low
507502 /// </summary>
@@ -512,24 +507,7 @@ public ProducerConfig() {}
512507
513508 static string createAdminClientSpecific ( )
514509 {
515- return
516- @" /// <summary>
517- /// Initialize a new empty <see cref=""AdminClientConfig"" /> instance.
518- /// </summary>
519- public AdminClientConfig() {}
520-
521- /// <summary>
522- /// Initialize a new <see cref=""AdminClientConfig"" /> instance based on
523- /// an existing <see cref=""ClientConfig"" /> instance.
524- /// </summary>
525- public AdminClientConfig(ClientConfig config) { this.properties = new Dictionary<string, string>(config.ToDictionary(a => a.Key, a => a.Value)); }
526-
527- /// <summary>
528- /// Initialize a new <see cref=""AdminClientConfig"" /> instance based on
529- /// an existing key/value pair collection.
530- /// </summary>
531- public AdminClientConfig(IEnumerable<KeyValuePair<string, string>> config) { this.properties = new Dictionary<string, string>(config.ToDictionary(a => a.Key, a => a.Value)); }
532- " ;
510+ return createClassConstructors ( "AdminClientConfig" ) ;
533511 }
534512
535513 static List < PropertySpecification > extractAll ( string configDoc )
@@ -547,24 +525,24 @@ static List<PropertySpecification> extractAll(string configDoc)
547525 continue ;
548526 }
549527
550- var columns = line . Split ( '|' ) ;
528+ var columns = SplitLine ( line ) . ToArray ( ) ;
551529 if ( columns . Length != 6 ) { continue ; }
552530 if ( columns [ 0 ] . Contains ( "-----" ) ) { continue ; }
553531 if ( columns [ 0 ] . Contains ( "Property" ) ) { continue ; }
554532
555533 var prop = new PropertySpecification ( ) ;
556534 prop . IsGlobal = parsingGlobal ;
557- prop . Name = columns [ 0 ] . Trim ( ) ;
558- prop . CPorA = columns [ 1 ] . Trim ( ) ;
559- prop . Range = columns [ 2 ] . Trim ( ) ;
560- prop . Default = columns [ 3 ] . Trim ( ) ;
561- prop . Importance = columns [ 4 ] . Trim ( ) ;
535+ prop . Name = columns [ 0 ] ;
536+ prop . CPorA = columns [ 1 ] ;
537+ prop . Range = columns [ 2 ] ;
538+ prop . Default = columns [ 3 ] ;
539+ prop . Importance = columns [ 4 ] ;
562540
563- var desc = columns [ 5 ] . Trim ( ) ;
541+ var desc = columns [ 5 ] ;
564542 bool isAlias = desc . StartsWith ( "Alias" ) ;
565543 if ( isAlias )
566544 {
567- var firstIdx = desc . IndexOf ( '`' ) + 1 ;
545+ var firstIdx = desc . IndexOf ( '`' ) + 1 ;
568546 prop . AliasFor = desc . Substring ( firstIdx , desc . IndexOf ( '`' , firstIdx ) - desc . IndexOf ( '`' ) - 1 ) ;
569547 }
570548 else
@@ -582,6 +560,23 @@ static List<PropertySpecification> extractAll(string configDoc)
582560 return props ;
583561 }
584562
563+ static IEnumerable < string > SplitLine ( string line )
564+ {
565+ if ( string . IsNullOrWhiteSpace ( line ) )
566+ yield break ;
567+
568+ int lastPipe = 0 ;
569+ for ( int i = 1 ; i < line . Length - 1 ; i ++ )
570+ {
571+ if ( line [ i ] == '|' && line [ i - 1 ] == ' ' && line [ i + 1 ] == ' ' )
572+ {
573+ yield return line . Substring ( lastPipe , i - lastPipe ) . Trim ( ) ;
574+ lastPipe = i + 1 ;
575+ }
576+ }
577+ yield return line . Substring ( lastPipe + 1 ) . Trim ( ) ;
578+ }
579+
585580 static List < PropertySpecification > removeDuplicateTopicLevel ( List < PropertySpecification > props )
586581 {
587582 // remove topicLevel properties that are in both topic level and global.
@@ -666,6 +661,7 @@ static async Task<int> Main(string[] args)
666661 codeText += MappingConfiguration . SaslMechanismEnumString ;
667662 codeText += MappingConfiguration . AcksEnumString ;
668663 codeText += createClassHeader ( "ClientConfig" , "Configuration common to all clients" , false ) ;
664+ codeText += createClassConstructors ( "ClientConfig" ) ;
669665 codeText += MappingConfiguration . SaslMechanismGetSetString ;
670666 codeText += MappingConfiguration . AcksGetSetString ;
671667 codeText += createProperties ( props . Where ( p => p . CPorA == "*" ) ) ;
0 commit comments