10a0e72b13e0bbe0d935b7fcef07a95949d7fd2e5A. Unique TensorFlower/* Copyright 2016 The TensorFlow Authors. All Rights Reserved.
2df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
3df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerLicensed under the Apache License, Version 2.0 (the "License");
4df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFloweryou may not use this file except in compliance with the License.
5df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerYou may obtain a copy of the License at
6df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
7df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    http://www.apache.org/licenses/LICENSE-2.0
8df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
9df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerUnless required by applicable law or agreed to in writing, software
10df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerdistributed under the License is distributed on an "AS IS" BASIS,
11df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerWITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerSee the License for the specific language governing permissions and
13df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerlimitations under the License.
14df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower==============================================================================*/
15df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
16df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower#include "tensorflow/tools/proto_text/gen_proto_text_functions_lib.h"
17df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
18df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower#include <algorithm>
19df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower#include <set>
20d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower#include <unordered_set>
21df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
224e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp#include "tensorflow/core/platform/logging.h"
23df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower#include "tensorflow/core/platform/macros.h"
24df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower#include "tensorflow/core/platform/types.h"
25df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
26df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerusing ::tensorflow::protobuf::Descriptor;
27df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerusing ::tensorflow::protobuf::EnumDescriptor;
28df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerusing ::tensorflow::protobuf::FieldDescriptor;
29df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerusing ::tensorflow::protobuf::FieldOptions;
30df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerusing ::tensorflow::protobuf::FileDescriptor;
31df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
32df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowernamespace tensorflow {
33df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
34df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowernamespace {
35df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
364e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harptemplate <typename... Args>
374e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harpstring StrCat(const Args&... args) {
384e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  std::ostringstream s;
394e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  std::vector<int>{((s << args), 0)...};
404e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  return s.str();
414e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp}
424e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp
434e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harptemplate <typename... Args>
444e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harpstring StrAppend(string* to_append, const Args&... args) {
454e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  *to_append += StrCat(args...);
464e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  return *to_append;
474e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp}
484e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp
49df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Class used to generate the code for proto text functions. One of these should
50df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// be created for each FileDescriptor whose code should be generated.
51df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower//
52df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// This class has a notion of the current output Section.  The Print, Nested,
53df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// and Unnest functions apply their operations to the current output section,
54df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// which can be toggled with SetOutput.
55df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower//
56df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Note that on the generated code, various pieces are not optimized - for
57df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// example: map input and output, Cord input and output, comparisons against
58df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// the field names (it's a loop over all names), and tracking of has_seen.
59df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerclass Generator {
60df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower public:
616882effb863dcd0da00d3287959deac46734a0b2A. Unique TensorFlower  explicit Generator(const string& tf_header_prefix)
62df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      : tf_header_prefix_(tf_header_prefix),
63df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        header_(&code_.header),
64df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        header_impl_(&code_.header_impl),
65df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        cc_(&code_.cc) {}
66df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
67df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void Generate(const FileDescriptor& fd);
68df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
69df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // The generated code; valid after Generate has been called.
70df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  ProtoTextFunctionCode code() const { return code_; }
71df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
72df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower private:
73df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  struct Section {
746882effb863dcd0da00d3287959deac46734a0b2A. Unique TensorFlower    explicit Section(string* str) : str(str) {}
75df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    string* str;
76df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    string indent;
77df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  };
78df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
79df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Switches the currently active section to <section>.
80df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& SetOutput(Section* section) {
81df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    cur_ = section;
82df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
83df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
84df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
85df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Increases indent level.  Returns <*this>, to allow chaining.
86df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& Nest() {
87df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(&cur_->indent, "  ");
88df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
89df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
90df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
91df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Decreases indent level.  Returns <*this>, to allow chaining.
92df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& Unnest() {
93df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    cur_->indent = cur_->indent.substr(0, cur_->indent.size() - 2);
94df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
95df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
96df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
97df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the concatenated args, with a trailing newline. Returns <*this>, to
98df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // allow chaining.
99df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  template <typename... Args>
100df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& Print(Args... args) {
101df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(cur_->str, cur_->indent, args..., "\n");
102df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
103df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
104df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
105df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print code for a single field's value.
106df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // If <omit_default> is true, then the emitted code will not print zero-valued
107df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // values.
108df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // <field_expr> is code that when emitted yields the field's value.
109df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendFieldValueAppend(const FieldDescriptor& field,
110df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                              const bool omit_default,
111df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                              const string& field_expr);
112df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
113df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print code for as single field.
114df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendFieldAppend(const FieldDescriptor& field);
115df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
116df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print code for a message. May change which section is currently
117df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // active.
118df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendDebugStringFunctions(const Descriptor& md);
119df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
120df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print and parse functions for an enum. May change which
121df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // section is currently active.
122df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendEnumFunctions(const EnumDescriptor& enum_d);
123df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
124df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the parse functions for a message. May change which section is
125df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // currently active.
126df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendParseMessageFunction(const Descriptor& md);
127df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
128df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends all functions for a message and its nested message and enum types.
129df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // May change which section is currently active.
130df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendMessageFunctions(const Descriptor& md);
131df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
132df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends lines to open or close namespace declarations.
133df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AddNamespaceToCurrentSection(const string& package, bool open);
134df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
135df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the given headers as sorted #include lines.
136df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AddHeadersToCurrentSection(const std::vector<string>& headers);
137df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
138df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // When adding #includes for tensorflow headers, prefix them with this.
139df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string tf_header_prefix_;
140df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  ProtoTextFunctionCode code_;
141df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section* cur_ = nullptr;
142df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section header_;
143df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section header_impl_;
144df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section cc_;
145df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
146d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  std::unordered_set<string> map_append_signatures_included_;
147d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
148df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  TF_DISALLOW_COPY_AND_ASSIGN(Generator);
149df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower};
150df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
151df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the prefix needed to reference objects defined in <fd>. E.g.
152df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// "::tensorflow::test".
153df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetPackageReferencePrefix(const FileDescriptor* fd) {
1544e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  string result = "::";
1554e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  const string& package = fd->package();
15654e5000e0b980abe905900599c4493fadae34a15A. Unique TensorFlower  for (size_t i = 0; i < package.size(); ++i) {
1574e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    if (package[i] == '.') {
1584e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      result += "::";
1594e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    } else {
1604e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      result += package[i];
1614e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    }
1624e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  }
1634e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  result += "::";
1644e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  return result;
165df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
166df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
167df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the class generated by proto to represent <d>.
168df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetClassName(const Descriptor& d) {
169df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (d.containing_type() == nullptr) return d.name();
170df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetClassName(*d.containing_type()), "_", d.name());
171df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
172df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
173df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the class generated by proto to represent <ed>.
174df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetClassName(const EnumDescriptor& ed) {
175df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (ed.containing_type() == nullptr) return ed.name();
176df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetClassName(*ed.containing_type()), "_", ed.name());
177df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
178df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
179df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name that refers to the class generated by proto to
180df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// represent <d>.
181df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedName(const Descriptor& d) {
182df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(d.file()), GetClassName(d));
183df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
184df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
185df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name that refers to the class generated by proto to
186df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// represent <ed>.
187df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedName(const EnumDescriptor& d) {
188df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(d.file()), GetClassName(d));
189df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
190df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
191df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name that refers to the generated
192df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// AppendProtoDebugString function for <d>.
193df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedAppendFn(const Descriptor& d) {
194df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(d.file()),
195df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                "internal::AppendProtoDebugString");
196df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
197df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
198df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the generated function that returns an enum value's
199df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// string value.
200df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetEnumNameFn(const EnumDescriptor& enum_d) {
201df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat("EnumName_", GetClassName(enum_d));
202df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
203df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
204df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name of the function returned by GetEnumNameFn().
205df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedEnumNameFn(const EnumDescriptor& enum_d) {
206df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(enum_d.file()),
207df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                GetEnumNameFn(enum_d));
208df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
209df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
210df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of a generated header file, either the public api (if impl
211df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// is false) or the internal implementation header (if impl is true).
212df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetProtoTextHeaderName(const FileDescriptor& fd, bool impl) {
213df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const int dot_index = fd.name().find_last_of('.');
214df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return fd.name().substr(0, dot_index) +
215df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower         (impl ? ".pb_text-impl.h" : ".pb_text.h");
216df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
217df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
218df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the header generated by the proto library for <fd>.
219df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetProtoHeaderName(const FileDescriptor& fd) {
220df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const int dot_index = fd.name().find_last_of('.');
221df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return fd.name().substr(0, dot_index) + ".pb.h";
222df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
223df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
224df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the C++ class name for the given proto field.
225df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetCppClass(const FieldDescriptor& d) {
226645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  string cpp_class = d.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
227645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai                         ? GetQualifiedName(*d.message_type())
228645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai                         : d.cpp_type_name();
229645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai
230645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  // In open-source TensorFlow, the definition of int64 varies across
231645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  // platforms. The following line, which is manipulated during internal-
232645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  // external sync'ing, takes care of the variability.
233645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  if (cpp_class == "int64") {
234645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai    cpp_class = kProtobufInt64Typename;
235645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  }
236645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai
237645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  return cpp_class;
238df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
239df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
240df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the string that can be used for a header guard for the generated
241df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// headers for <fd>, either for the public api (if impl is false) or the
242df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// internal implementation header (if impl is true).
243df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetHeaderGuard(const FileDescriptor& fd, bool impl) {
244df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  string s = fd.name();
245df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::replace(s.begin(), s.end(), '/', '_');
246df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::replace(s.begin(), s.end(), '.', '_');
247df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return s + (impl ? "_IMPL_H_" : "_H_");
248df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
249df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
250df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendFieldValueAppend(const FieldDescriptor& field,
251df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                       const bool omit_default,
252df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                       const string& field_expr) {
253df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
254df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  switch (field.cpp_type()) {
255df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_INT32:
256df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_INT64:
257df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_UINT32:
258df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_UINT64:
259df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_DOUBLE:
260df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_FLOAT:
261df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->", omit_default ? "AppendNumericIfNotZero" : "AppendNumeric",
262df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            "(\"", field.name(), "\", ", field_expr, ");");
263df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
264df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_BOOL:
265df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->", omit_default ? "AppendBoolIfTrue" : "AppendBool", "(\"",
266df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            field.name(), "\", ", field_expr, ");");
267df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
268df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_STRING: {
269df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      const auto ctype = field.options().ctype();
270df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      CHECK(ctype == FieldOptions::CORD || ctype == FieldOptions::STRING)
271df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          << "Unsupported ctype " << ctype;
272df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
273df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->", omit_default ? "AppendStringIfNotEmpty" : "AppendString",
2743883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower            "(\"", field.name(), "\", ProtobufStringToString(", field_expr,
2753883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower            "));");
276df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
277df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
278df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_ENUM:
279df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
280df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Print("if (", field_expr, " != 0) {").Nest();
281df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
282df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->AppendEnumName(\"", field.name(), "\", ",
283df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            GetQualifiedEnumNameFn(*field.enum_type()), "(", field_expr, "));");
284df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
285df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Unnest().Print("}");
286df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
287df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
288df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_MESSAGE:
289df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      CHECK(!field.message_type()->options().map_entry());
290df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
291df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Print("if (msg.has_", field.name(), "()) {").Nest();
292df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
293df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->OpenNestedMessage(\"", field.name(), "\");");
294df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print(GetQualifiedAppendFn(*field.message_type()), "(o, ", field_expr,
295df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            ");");
296df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->CloseNestedMessage();");
297df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
298df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Unnest().Print("}");
299df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
300df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
301df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
302df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
303df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
304df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendFieldAppend(const FieldDescriptor& field) {
3057a1210bdbdade7210d48db287065ecac950338aaVincent Vanhoucke  const string& name = field.name();
306df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
307df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (field.is_map()) {
308df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("{").Nest();
309df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const auto& key_type = *field.message_type()->FindFieldByName("key");
310df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const auto& value_type = *field.message_type()->FindFieldByName("value");
311df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
312df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("std::vector<", key_type.cpp_type_name(), "> keys;");
313df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("for (const auto& e : msg.", name, "()) keys.push_back(e.first);");
314df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("std::stable_sort(keys.begin(), keys.end());");
315df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("for (const auto& key : keys) {").Nest();
316df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("o->OpenNestedMessage(\"", name, "\");");
317df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendFieldValueAppend(key_type, false /* omit_default */, "key");
318df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendFieldValueAppend(value_type, false /* omit_default */,
319df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                           StrCat("msg.", name, "().at(key)"));
320df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("o->CloseNestedMessage();");
321df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
322df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
323df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
324df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else if (field.is_repeated()) {
325df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("for (int i = 0; i < msg.", name, "_size(); ++i) {");
326df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Nest();
327df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendFieldValueAppend(field, false /* omit_default */,
328df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                           "msg." + name + "(i)");
329df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
330df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else {
3311150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    const auto* oneof = field.containing_oneof();
3321150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    if (oneof != nullptr) {
3331150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      string camel_name = field.camelcase_name();
3341150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      camel_name[0] = toupper(camel_name[0]);
3351150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Print("if (msg.", oneof->name(), "_case() == ",
3361150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            GetQualifiedName(*oneof->containing_type()), "::k", camel_name,
3371150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            ") {");
3381150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Nest();
3391150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      AppendFieldValueAppend(field, false /* omit_default */,
3401150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower                             "msg." + name + "()");
3411150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Unnest();
3421150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Print("}");
3431150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    } else {
3441150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      AppendFieldValueAppend(field, true /* omit_default */,
3451150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower                             "msg." + name + "()");
3461150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    }
347df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
348df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
349df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
350df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendEnumFunctions(const EnumDescriptor& enum_d) {
351df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string sig = StrCat("const char* ", GetEnumNameFn(enum_d), "(\n    ",
352df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                            GetQualifiedName(enum_d), " value)");
353df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_);
354df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("// Enum text output for ", string(enum_d.full_name()));
355df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print(sig, ";");
356df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
357df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
358df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print(sig, " {");
359df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Nest().Print("switch (value) {").Nest();
360df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < enum_d.value_count(); ++i) {
361df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const auto& value = *enum_d.value(i);
362df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("case ", value.number(), ": return \"", value.name(), "\";");
363df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
364df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("default: return \"\";");
365df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
366df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
367df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
368df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
369df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendParseMessageFunction(const Descriptor& md) {
370df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const bool map_append = (md.options().map_entry());
371df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  string sig;
372df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (!map_append) {
373df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    sig = StrCat("bool ProtoParseFromString(\n    const string& s,\n    ",
374df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                 GetQualifiedName(md), "* msg)");
375df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&header_).Print(sig, "\n        TF_MUST_USE_RESULT;");
376df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
377df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&cc_);
378df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print().Print(sig, " {").Nest();
379df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("msg->Clear();");
380df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("Scanner scanner(s);");
381df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("if (!internal::ProtoParseFromScanner(",
382df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "&scanner, false, false, msg)) return false;");
383df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("scanner.Eos();");
384df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("return scanner.GetResult();");
385df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
386df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
387df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
388df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Parse from scanner - the real work here.
389d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  sig = StrCat("bool ProtoParseFromScanner(",
390df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower               "\n    ::tensorflow::strings::Scanner* scanner, bool nested, "
391df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower               "bool close_curly,\n    ");
392df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const FieldDescriptor* key_type = nullptr;
393df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const FieldDescriptor* value_type = nullptr;
394df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (map_append) {
395df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    key_type = md.FindFieldByName("key");
396df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    value_type = md.FindFieldByName("value");
397df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(&sig, "::tensorflow::protobuf::Map<", GetCppClass(*key_type),
398df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              ", ", GetCppClass(*value_type), ">* map)");
399df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else {
400df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(&sig, GetQualifiedName(md), "* msg)");
401df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
402d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
403d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (!map_append_signatures_included_.insert(sig).second) {
404d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    // signature for function to append to a map of this type has
405d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    // already been defined in this .cc file. Don't define it again.
406d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    return;
407d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
408d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
409d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (!map_append) {
410d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    SetOutput(&header_impl_).Print(sig, ";");
411d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
412df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
413df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
414df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("namespace internal {");
415d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (map_append) {
416d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    Print("namespace {");
417d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
418df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print(sig, " {").Nest();
419df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (map_append) {
420df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print(GetCppClass(*key_type), " map_key;");
421df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("bool set_map_key = false;");
422df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print(GetCppClass(*value_type), " map_value;");
423df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("bool set_map_value = false;");
424df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
425df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("std::vector<bool> has_seen(", md.field_count(), ", false);");
426df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("while(true) {").Nest();
427df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("ProtoSpaceAndComments(scanner);");
428df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
429df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Emit success case
430df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (nested && (scanner->Peek() == (close_curly ? '}' : '>'))) {")
431df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      .Nest();
432df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("scanner->One(Scanner::ALL);");
433df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("ProtoSpaceAndComments(scanner);");
434df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (map_append) {
435df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("if (!set_map_key || !set_map_value) return false;");
436df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("(*map)[map_key] = map_value;");
437df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
438df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("return true;");
439df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
440df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
441df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (!nested && scanner->empty()) { return true; }");
442df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("scanner->RestartCapture()");
443df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("    .Many(Scanner::LETTER_DIGIT_UNDERSCORE)");
444df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("    .StopCapture();");
445df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("StringPiece identifier;");
446df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (!scanner->GetResult(nullptr, &identifier)) return false;");
447df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("bool parsed_colon = false;");
44854e5000e0b980abe905900599c4493fadae34a15A. Unique TensorFlower  Print("(void)parsed_colon;"); // Avoid "set but not used" compiler warning
449df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("ProtoSpaceAndComments(scanner);");
450df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (scanner->Peek() == ':') {");
451df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Nest().Print("parsed_colon = true;");
452df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("scanner->One(Scanner::ALL);");
453df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("ProtoSpaceAndComments(scanner);");
454df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
455df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.field_count(); ++i) {
456df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const FieldDescriptor* field = md.field(i);
4577a1210bdbdade7210d48db287065ecac950338aaVincent Vanhoucke    const string& field_name = field->name();
458df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    string mutable_value_expr;
459df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    string set_value_prefix;
460df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (map_append) {
461df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      mutable_value_expr = StrCat("&map_", field_name);
462df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      set_value_prefix = StrCat("map_", field_name, " = ");
463df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    } else if (field->is_repeated()) {
464df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (field->is_map()) {
465df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        mutable_value_expr = StrCat("msg->mutable_", field_name, "()");
466df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        set_value_prefix =
467df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            "UNREACHABLE";  // generator will never use this value.
468df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      } else {
469df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        mutable_value_expr = StrCat("msg->add_", field_name, "()");
470df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        set_value_prefix = StrCat("msg->add_", field_name);
471df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
472df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    } else {
473df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      mutable_value_expr = StrCat("msg->mutable_", field_name, "()");
474df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      set_value_prefix = StrCat("msg->set_", field_name);
475df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
476df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
477df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print(i == 0 ? "" : "else ", "if (identifier == \"", field_name, "\") {");
478df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Nest();
479df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
480df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (field->is_repeated()) {
481df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      CHECK(!map_append);
482df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
483df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      // Check to see if this is an array assignment, like a: [1, 2, 3]
484df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("const bool is_list = (scanner->Peek() == '[');");
485df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("do {");
486df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      // [ or , // skip
487df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Nest().Print("if (is_list) {");
488df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Nest().Print("scanner->One(Scanner::ALL);");
489df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("ProtoSpaceAndComments(scanner);");
490df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Unnest().Print("}");
491df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    } else if (field->containing_oneof() != nullptr) {
492df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      CHECK(!map_append);
493df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
494df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      // Detect duplicate oneof value.
495df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      const string oneof_name = field->containing_oneof()->name();
496df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("if (msg->", oneof_name, "_case() != 0) return false;");
497df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
498df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
499df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (!field->is_repeated() && !map_append) {
500df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      // Detect duplicate nested repeated message.
501df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("if (has_seen[", i, "]) return false;");
502df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("has_seen[", i, "] = true;");
503df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
504df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (field->cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE) {
505df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("const char open_char = scanner->Peek();");
506df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("if (open_char != '{' && open_char != '<') return false;");
507df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("scanner->One(Scanner::ALL);");
508df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("ProtoSpaceAndComments(scanner);");
509d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower      if (field->is_map()) {
510d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower        Print("if (!ProtoParseFromScanner(");
511d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower      } else {
512d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower        Print("if (!", GetPackageReferencePrefix(field->message_type()->file()),
513d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower              "internal::ProtoParseFromScanner(");
514d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower      }
515df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("    scanner, true, open_char == '{', ", mutable_value_expr,
516df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            ")) return false;");
517df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_STRING) {
5183883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower      Print("string str_value;");
5193883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower      Print(
5203883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower          "if (!parsed_colon || "
5213883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower          "!::tensorflow::strings::ProtoParseStringLiteralFromScanner(");
5223883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower      Print("    scanner, &str_value)) return false;");
5233883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower      Print("SetProtobufStringSwapAllowed(&str_value, ", mutable_value_expr,
5243883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower            ");");
525df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    } else if (field->cpp_type() == FieldDescriptor::CPPTYPE_ENUM) {
526df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("StringPiece value;");
527df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print(
528df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "if (!parsed_colon || "
529df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "!scanner->RestartCapture().Many("
530df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "Scanner::LETTER_DIGIT_DASH_UNDERSCORE)."
531df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "GetResult(nullptr, &value)) return false;");
532df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      const auto* enum_d = field->enum_type();
533df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      string value_prefix;
534df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (enum_d->containing_type() == nullptr) {
535df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        value_prefix = GetPackageReferencePrefix(enum_d->file());
536df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      } else {
537df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        value_prefix = StrCat(GetQualifiedName(*enum_d), "_");
538df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
539df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
540df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      for (int enum_i = 0; enum_i < enum_d->value_count(); ++enum_i) {
541df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        const auto* value_d = enum_d->value(enum_i);
5427a1210bdbdade7210d48db287065ecac950338aaVincent Vanhoucke        const string& value_name = value_d->name();
543df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        string condition = StrCat("value == \"", value_name,
544df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                  "\" || value == \"", value_d->number(), "\"");
545df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        if (value_d->number() == 0) {
546df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          StrAppend(&condition, " || value == \"-0\"");
547df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        }
548df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
549df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Print(enum_i == 0 ? "" : "} else ", "if (", condition, ") {");
550df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Nest();
551df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Print(set_value_prefix, "(", value_prefix, value_name, ");");
552df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Unnest();
553df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
554df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("} else {").Nest().Print("return false;").Unnest().Print("}");
555df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    } else {
556df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print(field->cpp_type_name(), " value;");
557df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      switch (field->cpp_type()) {
558df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_INT32:
559df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_INT64:
560df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_UINT32:
561df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_UINT64:
562df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_DOUBLE:
563df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_FLOAT:
564df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          Print(
565df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              "if (!parsed_colon || "
566df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              "!::tensorflow::strings::ProtoParseNumericFromScanner(",
567df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              "scanner, &value)) return false;");
568df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          break;
569df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        case FieldDescriptor::CPPTYPE_BOOL:
570df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          Print(
571df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              "if (!parsed_colon || "
572df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              "!::tensorflow::strings::ProtoParseBoolFromScanner(",
573df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              "scanner, &value)) return false;");
574df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          break;
575df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        default:
576df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          LOG(FATAL) << "handled earlier";
577df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
578df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print(set_value_prefix, "(value);");
579df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
580df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
581df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (field->is_repeated()) {
582df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Unnest().Print("} while (is_list && scanner->Peek() == ',');");
583df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print(
584df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "if (is_list && "
585df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "!scanner->OneLiteral(\"]\").GetResult()) return false;");
586df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
587df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (map_append) {
588df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("set_map_", field_name, " = true;");
589df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
590df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
591df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
592df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
593df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
594d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  Unnest().Print();
595d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (map_append) {
596d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    Print("}  // namespace");
597d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
598d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  Print("}  // namespace internal");
599df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
600df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
601df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendDebugStringFunctions(const Descriptor& md) {
602df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_).Print();
603df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_).Print().Print("// Message-text conversion for ",
604df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                    string(md.full_name()));
605df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
606df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Append the two debug string functions for <md>.
607df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int short_pass = 0; short_pass < 2; ++short_pass) {
608df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const bool short_debug = (short_pass == 1);
609df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
610df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // Make the Get functions.
611df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const string sig = StrCat(
612df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        "string ", short_debug ? "ProtoShortDebugString" : "ProtoDebugString",
613df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        "(\n    const ", GetQualifiedName(md), "& msg)");
614df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&header_).Print(sig, ";");
615df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
616df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&cc_);
617df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print().Print(sig, " {").Nest();
618df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("string s;");
619df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("::tensorflow::strings::ProtoTextOutput o(&s, ",
620df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          short_debug ? "true" : "false", ");");
621df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("internal::AppendProtoDebugString(&o, msg);");
622df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("o.CloseTopMessage();");
623df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("return s;");
624df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
625df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
626df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
627df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Make the Append function.
628df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string sig =
629df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat("void AppendProtoDebugString(\n",
630df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower             "    ::tensorflow::strings::ProtoTextOutput* o,\n    const ",
631df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower             GetQualifiedName(md), "& msg)");
632df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_).Print(sig, ";");
633df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
634df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("namespace internal {").Print();
635df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print(sig, " {").Nest();
6361150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  std::vector<const FieldDescriptor*> fields;
637eb10a4c494d95e7c17ddc44ef35197d08f2f6b33A. Unique TensorFlower  fields.reserve(md.field_count());
638df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.field_count(); ++i) {
6391150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    fields.push_back(md.field(i));
6401150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  }
6411150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  std::sort(fields.begin(), fields.end(),
6421150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            [](const FieldDescriptor* left, const FieldDescriptor* right) {
6431150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower              return left->number() < right->number();
6441150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            });
6451150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower
6461150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  for (const FieldDescriptor* field : fields) {
647df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&cc_);
6481150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    AppendFieldAppend(*field);
649df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
650df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}").Print().Print("}  // namespace internal");
651df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
652df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
653df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendMessageFunctions(const Descriptor& md) {
654df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (md.options().map_entry()) {
655df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // The 'map entry' Message is not a user-visible message type.  Only its
656df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // parse function is created (and that actually parsed the whole Map, not
657df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // just the map entry). Printing of a map is done in the code generated for
658df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // the containing message.
659df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendParseMessageFunction(md);
660df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return;
661df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
662df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
663d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  // Recurse before adding the main message function, so that internal
664d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  // map_append functions are available before they are needed.
665df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.enum_type_count(); ++i) {
666df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendEnumFunctions(*md.enum_type(i));
667df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
668df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.nested_type_count(); ++i) {
669df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendMessageFunctions(*md.nested_type(i));
670df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
671d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
672d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  AppendDebugStringFunctions(md);
673d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  AppendParseMessageFunction(md);
674df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
675df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
676df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AddNamespaceToCurrentSection(const string& package, bool open) {
677df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
6784e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  std::vector<string> parts = {""};
67954e5000e0b980abe905900599c4493fadae34a15A. Unique TensorFlower  for (size_t i = 0; i < package.size(); ++i) {
6804e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    if (package[i] == '.') {
6814e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      parts.resize(parts.size() + 1);
6824e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    } else {
6834e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      parts.back() += package[i];
6844e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    }
6854e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  }
686df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (open) {
687df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    for (const auto& p : parts) {
688df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("namespace ", p, " {");
689df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
690df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else {
691df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    for (auto it = parts.rbegin(); it != parts.rend(); ++it) {
692df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("}  // namespace ", *it);
693df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
694df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
695df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
696df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
697df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AddHeadersToCurrentSection(const std::vector<string>& headers) {
698df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::vector<string> sorted = headers;
699df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::sort(sorted.begin(), sorted.end());
700df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (const auto& h : sorted) {
701df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("#include \"", h, "\"");
702df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
703df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
704df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
705df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Adds to <all_fd> and <all_d> with all descriptors recursively
706df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// reachable from the given descriptor.
707df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid GetAllFileDescriptorsFromFile(const FileDescriptor* fd,
708df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const FileDescriptor*>* all_fd,
709df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const Descriptor*>* all_d);
710df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
711df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Adds to <all_fd> and <all_d> with all descriptors recursively
712df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// reachable from the given descriptor.
713df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid GetAllFileDescriptorsFromMessage(const Descriptor* d,
714df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                      std::set<const FileDescriptor*>* all_fd,
715df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                      std::set<const Descriptor*>* all_d) {
716df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (!all_d->insert(d).second) return;
717df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  GetAllFileDescriptorsFromFile(d->file(), all_fd, all_d);
718df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < d->field_count(); ++i) {
719df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    auto* f = d->field(i);
720df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    switch (f->cpp_type()) {
721df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_INT32:
722df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_INT64:
723df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_UINT32:
724df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_UINT64:
725df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_DOUBLE:
726df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_FLOAT:
727df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_BOOL:
728df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_STRING:
729df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        break;
730df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_MESSAGE:
731df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        GetAllFileDescriptorsFromMessage(f->message_type(), all_fd, all_d);
732df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        break;
733df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_ENUM:
734df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        GetAllFileDescriptorsFromFile(f->enum_type()->file(), all_fd, all_d);
735df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        break;
736df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
737df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
738df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < d->nested_type_count(); ++i) {
739df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    GetAllFileDescriptorsFromMessage(d->nested_type(i), all_fd, all_d);
740df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
741df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
742df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
743df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid GetAllFileDescriptorsFromFile(const FileDescriptor* fd,
744df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const FileDescriptor*>* all_fd,
745df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const Descriptor*>* all_d) {
746df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (!all_fd->insert(fd).second) return;
747df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < fd->message_type_count(); ++i) {
748df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    GetAllFileDescriptorsFromMessage(fd->message_type(i), all_fd, all_d);
749df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
750df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
751df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
752df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::Generate(const FileDescriptor& fd) {
753df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // This does not emit code with proper proto2 semantics (e.g. it doesn't check
754df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // 'has' fields on non-messages), so check that only proto3 is passed.
755df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  CHECK_EQ(fd.syntax(), FileDescriptor::SYNTAX_PROTO3) << fd.name();
756df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
757df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string package = fd.package();
758df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::set<const FileDescriptor*> all_fd;
759df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::set<const Descriptor*> all_d;
760df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  GetAllFileDescriptorsFromFile(&fd, &all_fd, &all_d);
761df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
762df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::vector<string> headers;
763df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
764df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add header to header file.
765df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_);
766df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("// GENERATED FILE - DO NOT MODIFY");
767df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#ifndef ", GetHeaderGuard(fd, false /* impl */));
768df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#define ", GetHeaderGuard(fd, false /* impl */));
769df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
770df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  headers = {
771df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      GetProtoHeaderName(fd),
772df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/platform/macros.h"),
773df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/platform/protobuf.h"),
774df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/platform/types.h"),
775df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  };
776df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (const auto& h : headers) {
777df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("#include \"", h, "\"");
778df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
779df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, true /* is_open */);
780df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
781df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add header to impl file.
782df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_);
783df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("// GENERATED FILE - DO NOT MODIFY");
784df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#ifndef ", GetHeaderGuard(fd, true /* impl */));
785df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#define ", GetHeaderGuard(fd, true /* impl */));
786df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
787df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  headers = {
788df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      GetProtoTextHeaderName(fd, false /* impl */),
789df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_,
790df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower             "tensorflow/core/lib/strings/proto_text_util.h"),
791df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/lib/strings/scanner.h"),
792df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  };
793df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (const FileDescriptor* d : all_fd) {
794df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (d != &fd) {
795df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      headers.push_back(GetProtoTextHeaderName(*d, true /* impl */));
796df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
797df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    headers.push_back(GetProtoHeaderName(*d));
798df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
7992d1c32eade41eaf9b9baf88fd5f5aa56bfed3dc0A. Unique TensorFlower  AddHeadersToCurrentSection(headers);
800df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, true /* is_open */);
801df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_).Print().Print("namespace internal {");
802df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
803df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add header to cc file.
804df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
805df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("// GENERATED FILE - DO NOT MODIFY");
806df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  headers = {GetProtoTextHeaderName(fd, true /* impl */)};
807df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddHeadersToCurrentSection(headers);
808df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
809df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("using ::tensorflow::strings::Scanner;");
810df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("using ::tensorflow::strings::StrCat;");
811df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, true /* is_open */);
812df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
813df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add declarations and definitions.
814df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < fd.enum_type_count(); ++i) {
815df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendEnumFunctions(*fd.enum_type(i));
816df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
817df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < fd.message_type_count(); ++i) {
818df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendMessageFunctions(*fd.message_type(i));
819df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
820df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
821df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add footer to header file.
822df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_);
823df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, false /* is_open */);
824df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("#endif  // ", GetHeaderGuard(fd, false /* impl */));
825df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
826df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add footer to header impl file.
827df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_).Print().Print("}  // namespace internal");
828df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, false /* is_open */);
829df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("#endif  // ", GetHeaderGuard(fd, true /* impl */));
830df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
831df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add footer to cc file.
832df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
833df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, false /* is_open */);
834df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
835df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
836df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}  // namespace
837df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
838df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerProtoTextFunctionCode GetProtoTextFunctionCode(const FileDescriptor& fd,
839df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                               const string& tf_header_prefix) {
840df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator gen(tf_header_prefix);
841df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  gen.Generate(fd);
842df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return gen.code();
843df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
844df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
845df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}  // namespace tensorflow
846