From 0559ecb2bb6b93226366e545b7edad15a05029f5 Mon Sep 17 00:00:00 2001 From: Oleg B Date: Mon, 11 Feb 2019 13:33:22 +0300 Subject: [PATCH] make-structs cmd line option (#15) * add plugin option make-structs * fix example * Update protoc_gen_d/protoc-gen-d.d Co-Authored-By: deviator * Update protoc_gen_d/protoc-gen-d.d Co-Authored-By: deviator * fix naming --- examples/add_person.d | 12 +++++++++--- examples/dub.json | 4 ++-- protoc_gen_d/protoc-gen-d.d | 22 ++++++++++++++++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/examples/add_person.d b/examples/add_person.d index 1697432..1fd7dc5 100644 --- a/examples/add_person.d +++ b/examples/add_person.d @@ -6,10 +6,16 @@ import std.string; import google.protobuf; import tutorial.addressbook; +T make(T)() +{ + static if (is(T == class)) return new T; + else return T.init; +} + /// This function fills in a Person message based on user input. Person promptForAddress() { - auto person = new Person; + auto person = make!Person; write("Enter person ID number: "); readf("%d", &person.id); @@ -23,7 +29,7 @@ Person promptForAddress() while (true) { - auto phoneNumber = new Person.PhoneNumber; + auto phoneNumber = make!(Person.PhoneNumber); write("Enter a phone number (or leave blank to finish): "); phoneNumber.number = readln!string.strip; if (phoneNumber.number.empty) @@ -57,7 +63,7 @@ int main(string[] args) return -1; } - auto addressBook = new AddressBook; + auto addressBook = make!AddressBook; try { auto input = File(args[1], "rb"); diff --git a/examples/dub.json b/examples/dub.json index 9f120eb..e74d82d 100644 --- a/examples/dub.json +++ b/examples/dub.json @@ -9,7 +9,7 @@ "sourceFiles": ["tutorial/addressbook.d"], "sourcePaths": ["../src"], "mainSourceFile": "add_person.d", - "preBuildCommands": ["protoc $$PROTO_PATH --plugin=../build/protoc-gen-d --d_out=. addressbook.proto"] + "preBuildCommands": ["protoc $$PROTO_PATH --plugin=../build/protoc-gen-d --d_opt=message-as-struct --d_out=. addressbook.proto"] }, { "name": "list_people", @@ -18,7 +18,7 @@ "sourceFiles": ["tutorial/addressbook.d"], "sourcePaths": ["../src"], "mainSourceFile": "list_people.d", - "preBuildCommands": ["protoc $$PROTO_PATH --plugin=../build/protoc-gen-d --d_out=. addressbook.proto"] + "preBuildCommands": ["protoc $$PROTO_PATH --plugin=../build/protoc-gen-d --d_opt=message-as-struct --d_out=. addressbook.proto"] }, ] } diff --git a/protoc_gen_d/protoc-gen-d.d b/protoc_gen_d/protoc-gen-d.d index d93577c..42c83b2 100644 --- a/protoc_gen_d/protoc-gen-d.d +++ b/protoc_gen_d/protoc-gen-d.d @@ -35,14 +35,18 @@ class CodeGeneratorException : Exception class CodeGenerator { private enum indentSize = 4; + private bool messageAsStruct = false; CodeGeneratorResponse handle(CodeGeneratorRequest request) { - import std.algorithm : filter, map; + import std.algorithm : filter, map, canFind, splitter; import std.array : array; import std.conv : to; import std.format : format; + if (request.parameter.splitter(",").canFind("message-as-struct")) + messageAsStruct = true; + if (request.compilerVersion) with (request.compilerVersion) protocVersion = format!"%d%03d%03d"(major, minor, patch); @@ -146,9 +150,18 @@ class CodeGenerator if (messageType.isMap) return ""; + auto indentation = "%*s".format(indent, ""); + auto result = appender!string; - result ~= "\n%*s%sclass %s\n".format(indent, "", indent > 0 ? "static " : "", messageType.name.escapeKeywords); - result ~= "%*s{\n".format(indent, ""); + result ~= "\n"; + result ~= indentation; + result ~= indent > 0 ? "static " : ""; + result ~= messageAsStruct ? "struct" : "class"; + result ~= " "; + result ~= messageType.name.escapeKeywords; + result ~= "\n"; + result ~= indentation; + result ~= "{\n"; int[] generatedOneofs; foreach (field; messageType.fields.sort!((a, b) => a.number < b.number)) @@ -173,7 +186,8 @@ class CodeGenerator foreach (enumType; messageType.enumTypes) result ~= generateEnum(enumType, indent + indentSize); - result ~= "%*s}\n".format(indent, ""); + result ~= indentation; + result ~= "}\n"; return result.data; }