Commit f31e34b1 authored by Jon Skeet's avatar Jon Skeet

Default to Environment.NewLine for line breaks in ProtoGen, but allow it to be configured.

parent 12f0460a
...@@ -45,7 +45,7 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -45,7 +45,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
/// </summary> /// </summary>
public sealed class Generator { public sealed class Generator {
readonly GeneratorOptions options; private readonly GeneratorOptions options;
private Generator(GeneratorOptions options) { private Generator(GeneratorOptions options) {
options.Validate(); options.Validate();
...@@ -59,8 +59,7 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -59,8 +59,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
return new Generator(options); return new Generator(options);
} }
public void Generate() { public void Generate() {
List<FileDescriptorSet> descriptorProtos = new List<FileDescriptorSet>(); List<FileDescriptorSet> descriptorProtos = new List<FileDescriptorSet>();
foreach (string inputFile in options.InputFiles) { foreach (string inputFile in options.InputFiles) {
ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance(); ExtensionRegistry extensionRegistry = ExtensionRegistry.CreateInstance();
...@@ -94,7 +93,7 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -94,7 +93,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
private void Generate(FileDescriptor descriptor) { private void Generate(FileDescriptor descriptor) {
UmbrellaClassGenerator ucg = new UmbrellaClassGenerator(descriptor); UmbrellaClassGenerator ucg = new UmbrellaClassGenerator(descriptor);
using (TextWriter textWriter = File.CreateText(GetOutputFile(descriptor))) { using (TextWriter textWriter = File.CreateText(GetOutputFile(descriptor))) {
TextGenerator writer = new TextGenerator(textWriter); TextGenerator writer = new TextGenerator(textWriter, options.LineBreak);
ucg.Generate(writer); ucg.Generate(writer);
} }
} }
......
...@@ -49,9 +49,20 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -49,9 +49,20 @@ namespace Google.ProtocolBuffers.ProtoGen {
/// the generator. /// the generator.
/// </summary> /// </summary>
public sealed class GeneratorOptions { public sealed class GeneratorOptions {
private static Dictionary<string, string> LineBreaks = new Dictionary<string, string>(StringComparer.InvariantCultureIgnoreCase) {
{ "Windows", "\r\n" },
{ "Unix", "\n" },
{ "Default", Environment.NewLine }
};
public IList<string> InputFiles { get; set; } public IList<string> InputFiles { get; set; }
/// <summary> public GeneratorOptions() {
LineBreak = Environment.NewLine;
}
/// <summary>
/// Attempts to validate the options, but doesn't throw an exception if they're invalid. /// Attempts to validate the options, but doesn't throw an exception if they're invalid.
/// Instead, when this method returns false, the output variable will contain a collection /// Instead, when this method returns false, the output variable will contain a collection
/// of reasons for the validation failure. /// of reasons for the validation failure.
...@@ -128,6 +139,8 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -128,6 +139,8 @@ namespace Google.ProtocolBuffers.ProtoGen {
set { fileOptions = value; } set { fileOptions = value; }
} }
public string LineBreak { get; set; }
private void ParseArguments(IList<string> tmpReasons) { private void ParseArguments(IList<string> tmpReasons) {
bool doHelp = Arguments.Count == 0; bool doHelp = Arguments.Count == 0;
...@@ -159,12 +172,17 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -159,12 +172,17 @@ namespace Google.ProtocolBuffers.ProtoGen {
if (TryCoerceType(value, fld, out obj, tmpReasons)) { if (TryCoerceType(value, fld, out obj, tmpReasons)) {
builder[fld] = obj; builder[fld] = obj;
} }
} } else if (name == "lineBreak") {
else if (!File.Exists(argument)) { string tmp;
if (LineBreaks.TryGetValue(value, out tmp)) {
LineBreak = tmp;
} else {
tmpReasons.Add("Invalid value for 'lineBreak': " + value + ".");
}
} else if (!File.Exists(argument)) {
doHelp = true; doHelp = true;
tmpReasons.Add("Unknown argument '" + name + "'."); tmpReasons.Add("Unknown argument '" + name + "'.");
} } else {
else {
InputFiles.Add(argument); InputFiles.Add(argument);
} }
} }
...@@ -178,6 +196,7 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -178,6 +196,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
foreach (KeyValuePair<string, FieldDescriptor> field in fields) { foreach (KeyValuePair<string, FieldDescriptor> field in fields) {
tmpReasons.Add(String.Format("-{0}=[{1}]", field.Key, field.Value.FieldType)); tmpReasons.Add(String.Format("-{0}=[{1}]", field.Key, field.Value.FieldType));
} }
tmpReasons.Add("-lineBreak=[" + string.Join("|", new List<string>(LineBreaks.Keys).ToArray()) + "]");
tmpReasons.Add("followed by one or more file paths."); tmpReasons.Add("followed by one or more file paths.");
} }
else { else {
......
...@@ -55,7 +55,7 @@ namespace Google.ProtocolBuffers.ProtoGen { ...@@ -55,7 +55,7 @@ namespace Google.ProtocolBuffers.ProtoGen {
} }
Console.WriteLine(); Console.WriteLine();
Console.WriteLine(); Console.WriteLine();
Console.WriteLine("PRTOGEN.exe: The following options are used to specify defaults for code generation."); Console.WriteLine("PROTOGEN.exe: The following options are used to specify defaults for code generation.");
Console.WriteLine(); Console.WriteLine();
Program.Main(new string[0]); Program.Main(new string[0]);
return 0; return 0;
......
...@@ -43,7 +43,8 @@ using System.Collections; ...@@ -43,7 +43,8 @@ using System.Collections;
namespace Google.ProtocolBuffers { namespace Google.ProtocolBuffers {
/// <summary> /// <summary>
/// Provides ASCII text formatting support for messages. /// Provides ASCII text formatting support for messages.
/// TODO(jonskeet): Parsing support. /// TODO(jonskeet): Support for alternative line endings.
/// (Easy to print, via TextGenerator. Not sure about parsing.)
/// </summary> /// </summary>
public static class TextFormat { public static class TextFormat {
...@@ -52,7 +53,7 @@ namespace Google.ProtocolBuffers { ...@@ -52,7 +53,7 @@ namespace Google.ProtocolBuffers {
/// the parameter output. /// the parameter output.
/// </summary> /// </summary>
public static void Print(IMessage message, TextWriter output) { public static void Print(IMessage message, TextWriter output) {
TextGenerator generator = new TextGenerator(output); TextGenerator generator = new TextGenerator(output, "\n");
Print(message, generator); Print(message, generator);
} }
...@@ -60,7 +61,7 @@ namespace Google.ProtocolBuffers { ...@@ -60,7 +61,7 @@ namespace Google.ProtocolBuffers {
/// Outputs a textual representation of <paramref name="fields" /> to <paramref name="output"/>. /// Outputs a textual representation of <paramref name="fields" /> to <paramref name="output"/>.
/// </summary> /// </summary>
public static void Print(UnknownFieldSet fields, TextWriter output) { public static void Print(UnknownFieldSet fields, TextWriter output) {
TextGenerator generator = new TextGenerator(output); TextGenerator generator = new TextGenerator(output, "\n");
PrintUnknownFields(fields, generator); PrintUnknownFields(fields, generator);
} }
......
...@@ -43,6 +43,13 @@ namespace Google.ProtocolBuffers { ...@@ -43,6 +43,13 @@ namespace Google.ProtocolBuffers {
/// </summary> /// </summary>
public sealed class TextGenerator { public sealed class TextGenerator {
/// <summary>
/// The string to use at the end of each line. We assume that "Print" is only called using \n
/// to indicate a line break; that's what we use to detect when we need to indent etc, and
/// *just* the \n is replaced with the contents of lineBreak.
/// </summary>
private readonly string lineBreak;
/// <summary> /// <summary>
/// Writer to write formatted text to. /// Writer to write formatted text to.
/// </summary> /// </summary>
...@@ -62,8 +69,9 @@ namespace Google.ProtocolBuffers { ...@@ -62,8 +69,9 @@ namespace Google.ProtocolBuffers {
/// Creates a generator writing to the given writer. The writer /// Creates a generator writing to the given writer. The writer
/// is not closed by this class. /// is not closed by this class.
/// </summary> /// </summary>
public TextGenerator(TextWriter writer) { public TextGenerator(TextWriter writer, string lineBreak) {
this.writer = writer; this.writer = writer;
this.lineBreak = lineBreak;
} }
/// <summary> /// <summary>
...@@ -107,8 +115,9 @@ namespace Google.ProtocolBuffers { ...@@ -107,8 +115,9 @@ namespace Google.ProtocolBuffers {
for (int i = 0; i < text.Length; i++) { for (int i = 0; i < text.Length; i++) {
if (text[i] == '\n') { if (text[i] == '\n') {
// TODO(jonskeet): Use Environment.NewLine? // Strip off the \n from what we write
Write(text.Substring(pos, i - pos + 1)); Write(text.Substring(pos, i - pos));
Write(lineBreak);
pos = i + 1; pos = i + 1;
atStartOfLine = true; atStartOfLine = true;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment