Skip to content

Commit

Permalink
Merge pull request #18470 from kkm000/kkm/17661-filenamegen
Browse files Browse the repository at this point in the history
C# tools: support generated filename corner cases
  • Loading branch information
jtattermusch committed Mar 22, 2019
2 parents cfa0d22 + aa40424 commit 1805e2e
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 19 deletions.
15 changes: 9 additions & 6 deletions src/csharp/Grpc.Tools.Tests/CSharpGeneratorTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,15 @@ public new void SetUp()
[TestCase("foo.proto", "Foo.cs", "FooGrpc.cs")]
[TestCase("sub/foo.proto", "Foo.cs", "FooGrpc.cs")]
[TestCase("one_two.proto", "OneTwo.cs", "OneTwoGrpc.cs")]
[TestCase("__one_two!.proto", "OneTwo!.cs", "OneTwo!Grpc.cs")]
[TestCase("one(two).proto", "One(two).cs", "One(two)Grpc.cs")]
[TestCase("one_(two).proto", "One(two).cs", "One(two)Grpc.cs")]
[TestCase("one two.proto", "One two.cs", "One twoGrpc.cs")]
[TestCase("one_ two.proto", "One two.cs", "One twoGrpc.cs")]
[TestCase("one .proto", "One .cs", "One Grpc.cs")]
[TestCase("ONE_TWO.proto", "ONETWO.cs", "ONETWOGrpc.cs")]
[TestCase("one.two.proto", "OneTwo.cs", "One.twoGrpc.cs")]
[TestCase("one123two.proto", "One123Two.cs", "One123twoGrpc.cs")]
[TestCase("__one_two!.proto", "OneTwo.cs", "OneTwo!Grpc.cs")]
[TestCase("one(two).proto", "OneTwo.cs", "One(two)Grpc.cs")]
[TestCase("one_(two).proto", "OneTwo.cs", "One(two)Grpc.cs")]
[TestCase("one two.proto", "OneTwo.cs", "One twoGrpc.cs")]
[TestCase("one_ two.proto", "OneTwo.cs", "One twoGrpc.cs")]
[TestCase("one .proto", "One.cs", "One Grpc.cs")]
public void NameMangling(string proto, string expectCs, string expectGrpcCs)
{
var poss = _generator.GetPossibleOutputs(Utils.MakeItem(proto, "grpcservices", "both"));
Expand Down
45 changes: 32 additions & 13 deletions src/csharp/Grpc.Tools/GeneratorServices.cs
Original file line number Diff line number Diff line change
Expand Up @@ -66,29 +66,28 @@ internal class CSharpGeneratorServices : GeneratorServices
public override string[] GetPossibleOutputs(ITaskItem protoItem)
{
bool doGrpc = GrpcOutputPossible(protoItem);
string filename = LowerUnderscoreToUpperCamel(
Path.GetFileNameWithoutExtension(protoItem.ItemSpec));

var outputs = new string[doGrpc ? 2 : 1];
string basename = Path.GetFileNameWithoutExtension(protoItem.ItemSpec);

string outdir = protoItem.GetMetadata(Metadata.OutputDir);
string fileStem = Path.Combine(outdir, filename);
outputs[0] = fileStem + ".cs";
string filename = LowerUnderscoreToUpperCamelProtocWay(basename);
outputs[0] = Path.Combine(outdir, filename) + ".cs";

if (doGrpc)
{
// Override outdir if kGrpcOutputDir present, default to proto output.
outdir = protoItem.GetMetadata(Metadata.GrpcOutputDir);
if (outdir != "")
{
fileStem = Path.Combine(outdir, filename);
}
outputs[1] = fileStem + "Grpc.cs";
string grpcdir = protoItem.GetMetadata(Metadata.GrpcOutputDir);
filename = LowerUnderscoreToUpperCamelGrpcWay(basename);
outputs[1] = Path.Combine(
grpcdir != "" ? grpcdir : outdir, filename) + "Grpc.cs";
}
return outputs;
}

string LowerUnderscoreToUpperCamel(string str)
// This is how the gRPC codegen currently construct its output filename.
// See src/compiler/generator_helpers.h:118.
string LowerUnderscoreToUpperCamelGrpcWay(string str)
{
// See src/compiler/generator_helpers.h:118
var result = new StringBuilder(str.Length, str.Length);
bool cap = true;
foreach (char c in str)
Expand All @@ -109,6 +108,26 @@ string LowerUnderscoreToUpperCamel(string str)
}
return result.ToString();
}

// This is how the protoc codegen constructs its output filename.
// See protobuf/compiler/csharp/csharp_helpers.cc:137.
// Note that protoc explicitly discards non-ASCII letters.
string LowerUnderscoreToUpperCamelProtocWay(string str)
{
var result = new StringBuilder(str.Length, str.Length);
bool cap = true;
foreach (char c in str)
{
char upperC = char.ToUpperInvariant(c);
bool isAsciiLetter = 'A' <= upperC && upperC <= 'Z';
if (isAsciiLetter || ('0' <= c && c <= '9'))
{
result.Append(cap ? upperC : c);
}
cap = !isAsciiLetter;
}
return result.ToString();
}
};

// C++ generator services.
Expand Down

0 comments on commit 1805e2e

Please sign in to comment.