aboutsummaryrefslogtreecommitdiffhomepage
path: root/tensorflow/tools/proto_text
diff options
context:
space:
mode:
authorGravatar A. Unique TensorFlower <nobody@tensorflow.org>2016-04-21 08:44:24 -0800
committerGravatar TensorFlower Gardener <gardener@tensorflow.org>2016-04-21 09:52:16 -0700
commitd111957918d2948c032c0093999d5a4ab1e698b0 (patch)
tree0e37de1bd499e8b03efe19447248bdec533fdc24 /tensorflow/tools/proto_text
parent0281e90086b8ab06ff30c822fba8a8c91712c2a6 (diff)
In proto_text, define the Map parsing functions as inside anonymous namespaces,
and define them only once per .cc file. Previous code defined them multiple times and relied on 'inline' keyword to avoid ODR conflicts, but someone reported this not working with their build (ODR violation was reported). Change: 120454125
Diffstat (limited to 'tensorflow/tools/proto_text')
-rw-r--r--tensorflow/tools/proto_text/gen_proto_text_functions_lib.cc40
-rw-r--r--tensorflow/tools/proto_text/test.proto3
2 files changed, 36 insertions, 7 deletions
diff --git a/tensorflow/tools/proto_text/gen_proto_text_functions_lib.cc b/tensorflow/tools/proto_text/gen_proto_text_functions_lib.cc
index b196fd23f7..1fc81b1358 100644
--- a/tensorflow/tools/proto_text/gen_proto_text_functions_lib.cc
+++ b/tensorflow/tools/proto_text/gen_proto_text_functions_lib.cc
@@ -17,6 +17,7 @@ limitations under the License.
#include <algorithm>
#include <set>
+#include <unordered_set>
#include "tensorflow/core/lib/strings/str_util.h"
#include "tensorflow/core/lib/strings/strcat.h"
@@ -133,6 +134,8 @@ class Generator {
Section header_impl_;
Section cc_;
+ std::unordered_set<string> map_append_signatures_included_;
+
TF_DISALLOW_COPY_AND_ASSIGN(Generator);
};
@@ -359,7 +362,7 @@ void Generator::AppendParseMessageFunction(const Descriptor& md) {
}
// Parse from scanner - the real work here.
- sig = StrCat(map_append ? "inline " : "", "bool ProtoParseFromScanner(",
+ sig = StrCat("bool ProtoParseFromScanner(",
"\n ::tensorflow::strings::Scanner* scanner, bool nested, "
"bool close_curly,\n ");
const FieldDescriptor* key_type = nullptr;
@@ -372,10 +375,22 @@ void Generator::AppendParseMessageFunction(const Descriptor& md) {
} else {
StrAppend(&sig, GetQualifiedName(md), "* msg)");
}
- SetOutput(&header_impl_).Print(sig, ";");
+
+ if (!map_append_signatures_included_.insert(sig).second) {
+ // signature for function to append to a map of this type has
+ // already been defined in this .cc file. Don't define it again.
+ return;
+ }
+
+ if (!map_append) {
+ SetOutput(&header_impl_).Print(sig, ";");
+ }
SetOutput(&cc_);
Print().Print("namespace internal {");
+ if (map_append) {
+ Print("namespace {");
+ }
Print().Print(sig, " {").Nest();
if (map_append) {
Print(GetCppClass(*key_type), " map_key;");
@@ -466,8 +481,12 @@ void Generator::AppendParseMessageFunction(const Descriptor& md) {
Print("if (open_char != '{' && open_char != '<') return false;");
Print("scanner->One(Scanner::ALL);");
Print("ProtoSpaceAndComments(scanner);");
- Print("if (!", GetPackageReferencePrefix(field->message_type()->file()),
- "internal::ProtoParseFromScanner(");
+ if (field->is_map()) {
+ Print("if (!ProtoParseFromScanner(");
+ } else {
+ Print("if (!", GetPackageReferencePrefix(field->message_type()->file()),
+ "internal::ProtoParseFromScanner(");
+ }
Print(" scanner, true, open_char == '{', ", mutable_value_expr,
")) return false;");
} else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
@@ -553,7 +572,11 @@ void Generator::AppendParseMessageFunction(const Descriptor& md) {
}
Unnest().Print("}");
Unnest().Print("}");
- Unnest().Print().Print("} // namespace internal");
+ Unnest().Print();
+ if (map_append) {
+ Print("} // namespace");
+ }
+ Print("} // namespace internal");
}
void Generator::AppendDebugStringFunctions(const Descriptor& md) {
@@ -617,14 +640,17 @@ void Generator::AppendMessageFunctions(const Descriptor& md) {
return;
}
- AppendDebugStringFunctions(md);
- AppendParseMessageFunction(md);
+ // Recurse before adding the main message function, so that internal
+ // map_append functions are available before they are needed.
for (int i = 0; i < md.enum_type_count(); ++i) {
AppendEnumFunctions(*md.enum_type(i));
}
for (int i = 0; i < md.nested_type_count(); ++i) {
AppendMessageFunctions(*md.nested_type(i));
}
+
+ AppendDebugStringFunctions(md);
+ AppendParseMessageFunction(md);
}
void Generator::AddNamespaceToCurrentSection(const string& package, bool open) {
diff --git a/tensorflow/tools/proto_text/test.proto b/tensorflow/tools/proto_text/test.proto
index e47a7b14e2..298fc0deef 100644
--- a/tensorflow/tools/proto_text/test.proto
+++ b/tensorflow/tools/proto_text/test.proto
@@ -83,6 +83,7 @@ message TestAllTypes {
map<bool, NestedMessage> map_bool_to_message = 61;
map<string, int64> map_string_to_int64 = 62;
map<int64, string> map_int64_to_string = 63;
+ map<string, NestedMessage> another_map_string_to_message = 65;
repeated int64 packed_repeated_int64 = 64 [packed = true];
}
@@ -91,6 +92,8 @@ message TestAllTypes {
message NestedTestAllTypes {
NestedTestAllTypes child = 1;
TestAllTypes payload = 2;
+
+ map<string, int64> map_string_to_int64 = 3;
}
message ForeignMessage {