gen_proto_text_functions_lib.cc revision 645a554a41ef5524e7ec65beeb7976c066886da6
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;
311150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlowerusing ::tensorflow::protobuf::OneofDescriptor;
32df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
33df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowernamespace tensorflow {
34df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
35df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowernamespace {
36df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
374e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harptemplate <typename... Args>
384e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harpstring StrCat(const Args&... args) {
394e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  std::ostringstream s;
404e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  std::vector<int>{((s << args), 0)...};
414e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  return s.str();
424e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp}
434e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp
444e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harptemplate <typename... Args>
454e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harpstring StrAppend(string* to_append, const Args&... args) {
464e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  *to_append += StrCat(args...);
474e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  return *to_append;
484e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp}
494e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp
50df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Class used to generate the code for proto text functions. One of these should
51df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// be created for each FileDescriptor whose code should be generated.
52df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower//
53df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// This class has a notion of the current output Section.  The Print, Nested,
54df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// and Unnest functions apply their operations to the current output section,
55df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// which can be toggled with SetOutput.
56df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower//
57df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Note that on the generated code, various pieces are not optimized - for
58df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// example: map input and output, Cord input and output, comparisons against
59df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// the field names (it's a loop over all names), and tracking of has_seen.
60df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerclass Generator {
61df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower public:
62df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator(const string& tf_header_prefix)
63df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      : tf_header_prefix_(tf_header_prefix),
64df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        header_(&code_.header),
65df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        header_impl_(&code_.header_impl),
66df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        cc_(&code_.cc) {}
67df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
68df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void Generate(const FileDescriptor& fd);
69df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
70df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // The generated code; valid after Generate has been called.
71df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  ProtoTextFunctionCode code() const { return code_; }
72df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
73df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower private:
74df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  struct Section {
75df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Section(string* str) : str(str) {}
76df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    string* str;
77df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    string indent;
78df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  };
79df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
80df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Switches the currently active section to <section>.
81df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& SetOutput(Section* section) {
82df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    cur_ = section;
83df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
84df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
85df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
86df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Increases indent level.  Returns <*this>, to allow chaining.
87df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& Nest() {
88df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(&cur_->indent, "  ");
89df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
90df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
91df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
92df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Decreases indent level.  Returns <*this>, to allow chaining.
93df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& Unnest() {
94df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    cur_->indent = cur_->indent.substr(0, cur_->indent.size() - 2);
95df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
96df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
97df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
98df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the concatenated args, with a trailing newline. Returns <*this>, to
99df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // allow chaining.
100df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  template <typename... Args>
101df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator& Print(Args... args) {
102df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(cur_->str, cur_->indent, args..., "\n");
103df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return *this;
104df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
105df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
106df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print code for a single field's value.
107df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // If <omit_default> is true, then the emitted code will not print zero-valued
108df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // values.
109df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // <field_expr> is code that when emitted yields the field's value.
110df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendFieldValueAppend(const FieldDescriptor& field,
111df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                              const bool omit_default,
112df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                              const string& field_expr);
113df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
114df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print code for as single field.
115df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendFieldAppend(const FieldDescriptor& field);
116df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
117df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print code for a message. May change which section is currently
118df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // active.
119df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendDebugStringFunctions(const Descriptor& md);
120df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
121df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the print and parse functions for an enum. May change which
122df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // section is currently active.
123df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendEnumFunctions(const EnumDescriptor& enum_d);
124df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
125df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the parse functions for a message. May change which section is
126df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // currently active.
127df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendParseMessageFunction(const Descriptor& md);
128df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
129df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends all functions for a message and its nested message and enum types.
130df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // May change which section is currently active.
131df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AppendMessageFunctions(const Descriptor& md);
132df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
133df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends lines to open or close namespace declarations.
134df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AddNamespaceToCurrentSection(const string& package, bool open);
135df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
136df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Appends the given headers as sorted #include lines.
137df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  void AddHeadersToCurrentSection(const std::vector<string>& headers);
138df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
139df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // When adding #includes for tensorflow headers, prefix them with this.
140df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string tf_header_prefix_;
141df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  ProtoTextFunctionCode code_;
142df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section* cur_ = nullptr;
143df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section header_;
144df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section header_impl_;
145df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Section cc_;
146df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
147d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  std::unordered_set<string> map_append_signatures_included_;
148d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
149df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  TF_DISALLOW_COPY_AND_ASSIGN(Generator);
150df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower};
151df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
152df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the prefix needed to reference objects defined in <fd>. E.g.
153df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// "::tensorflow::test".
154df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetPackageReferencePrefix(const FileDescriptor* fd) {
1554e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  string result = "::";
1564e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  const string& package = fd->package();
1574e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  for (int i = 0; i < package.size(); ++i) {
1584e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    if (package[i] == '.') {
1594e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      result += "::";
1604e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    } else {
1614e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      result += package[i];
1624e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    }
1634e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  }
1644e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  result += "::";
1654e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  return result;
166df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
167df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
168df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the class generated by proto to represent <d>.
169df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetClassName(const Descriptor& d) {
170df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (d.containing_type() == nullptr) return d.name();
171df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetClassName(*d.containing_type()), "_", d.name());
172df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
173df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
174df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the class generated by proto to represent <ed>.
175df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetClassName(const EnumDescriptor& ed) {
176df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (ed.containing_type() == nullptr) return ed.name();
177df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetClassName(*ed.containing_type()), "_", ed.name());
178df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
179df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
180df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name that refers to the class generated by proto to
181df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// represent <d>.
182df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedName(const Descriptor& d) {
183df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(d.file()), GetClassName(d));
184df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
185df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
186df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name that refers to the class generated by proto to
187df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// represent <ed>.
188df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedName(const EnumDescriptor& d) {
189df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(d.file()), GetClassName(d));
190df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
191df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
192df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name that refers to the generated
193df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// AppendProtoDebugString function for <d>.
194df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedAppendFn(const Descriptor& d) {
195df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(d.file()),
196df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                "internal::AppendProtoDebugString");
197df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
198df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
199df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the generated function that returns an enum value's
200df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// string value.
201df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetEnumNameFn(const EnumDescriptor& enum_d) {
202df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat("EnumName_", GetClassName(enum_d));
203df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
204df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
205df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the qualified name of the function returned by GetEnumNameFn().
206df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetQualifiedEnumNameFn(const EnumDescriptor& enum_d) {
207df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return StrCat(GetPackageReferencePrefix(enum_d.file()),
208df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                GetEnumNameFn(enum_d));
209df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
210df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
211df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of a generated header file, either the public api (if impl
212df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// is false) or the internal implementation header (if impl is true).
213df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetProtoTextHeaderName(const FileDescriptor& fd, bool impl) {
214df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const int dot_index = fd.name().find_last_of('.');
215df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return fd.name().substr(0, dot_index) +
216df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower         (impl ? ".pb_text-impl.h" : ".pb_text.h");
217df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
218df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
219df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the name of the header generated by the proto library for <fd>.
220df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetProtoHeaderName(const FileDescriptor& fd) {
221df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const int dot_index = fd.name().find_last_of('.');
222df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return fd.name().substr(0, dot_index) + ".pb.h";
223df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
224df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
225df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the C++ class name for the given proto field.
226df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetCppClass(const FieldDescriptor& d) {
227645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  string cpp_class = d.cpp_type() == FieldDescriptor::CPPTYPE_MESSAGE
228645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai                         ? GetQualifiedName(*d.message_type())
229645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai                         : d.cpp_type_name();
230645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai
231645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  // In open-source TensorFlow, the definition of int64 varies across
232645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  // platforms. The following line, which is manipulated during internal-
233645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  // external sync'ing, takes care of the variability.
234645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  if (cpp_class == "int64") {
235645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai    cpp_class = kProtobufInt64Typename;
236645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  }
237645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai
238645a554a41ef5524e7ec65beeb7976c066886da6Shanqing Cai  return cpp_class;
239df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
240df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
241df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Returns the string that can be used for a header guard for the generated
242df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// headers for <fd>, either for the public api (if impl is false) or the
243df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// internal implementation header (if impl is true).
244df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerstring GetHeaderGuard(const FileDescriptor& fd, bool impl) {
245df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  string s = fd.name();
246df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::replace(s.begin(), s.end(), '/', '_');
247df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::replace(s.begin(), s.end(), '.', '_');
248df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return s + (impl ? "_IMPL_H_" : "_H_");
249df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
250df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
251df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendFieldValueAppend(const FieldDescriptor& field,
252df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                       const bool omit_default,
253df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                       const string& field_expr) {
254df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
255df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  switch (field.cpp_type()) {
256df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_INT32:
257df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_INT64:
258df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_UINT32:
259df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_UINT64:
260df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_DOUBLE:
261df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_FLOAT:
262df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->", omit_default ? "AppendNumericIfNotZero" : "AppendNumeric",
263df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            "(\"", field.name(), "\", ", field_expr, ");");
264df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
265df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_BOOL:
266df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->", omit_default ? "AppendBoolIfTrue" : "AppendBool", "(\"",
267df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            field.name(), "\", ", field_expr, ");");
268df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
269df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_STRING: {
270df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      const auto ctype = field.options().ctype();
271df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      CHECK(ctype == FieldOptions::CORD || ctype == FieldOptions::STRING)
272df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          << "Unsupported ctype " << ctype;
273df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
274df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->", omit_default ? "AppendStringIfNotEmpty" : "AppendString",
2753883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower            "(\"", field.name(), "\", ProtobufStringToString(", field_expr,
2763883578ebff0e8f901386d6f2b5870de517de4a1A. Unique TensorFlower            "));");
277df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
278df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
279df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_ENUM:
280df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
281df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Print("if (", field_expr, " != 0) {").Nest();
282df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
283df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->AppendEnumName(\"", field.name(), "\", ",
284df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            GetQualifiedEnumNameFn(*field.enum_type()), "(", field_expr, "));");
285df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
286df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Unnest().Print("}");
287df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
288df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
289df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    case FieldDescriptor::CPPTYPE_MESSAGE:
290df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      CHECK(!field.message_type()->options().map_entry());
291df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
292df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Print("if (msg.has_", field.name(), "()) {").Nest();
293df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
294df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->OpenNestedMessage(\"", field.name(), "\");");
295df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print(GetQualifiedAppendFn(*field.message_type()), "(o, ", field_expr,
296df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower            ");");
297df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("o->CloseNestedMessage();");
298df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      if (omit_default) {
299df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        Unnest().Print("}");
300df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      }
301df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      break;
302df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
303df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
304df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
305df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendFieldAppend(const FieldDescriptor& field) {
3067a1210bdbdade7210d48db287065ecac950338aaVincent Vanhoucke  const string& name = field.name();
307df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
308df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (field.is_map()) {
309df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("{").Nest();
310df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const auto& key_type = *field.message_type()->FindFieldByName("key");
311df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const auto& value_type = *field.message_type()->FindFieldByName("value");
312df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
313df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("std::vector<", key_type.cpp_type_name(), "> keys;");
314df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("for (const auto& e : msg.", name, "()) keys.push_back(e.first);");
315df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("std::stable_sort(keys.begin(), keys.end());");
316df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("for (const auto& key : keys) {").Nest();
317df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("o->OpenNestedMessage(\"", name, "\");");
318df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendFieldValueAppend(key_type, false /* omit_default */, "key");
319df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendFieldValueAppend(value_type, false /* omit_default */,
320df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                           StrCat("msg.", name, "().at(key)"));
321df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("o->CloseNestedMessage();");
322df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
323df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
324df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
325df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else if (field.is_repeated()) {
326df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("for (int i = 0; i < msg.", name, "_size(); ++i) {");
327df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Nest();
328df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendFieldValueAppend(field, false /* omit_default */,
329df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                           "msg." + name + "(i)");
330df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
331df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else {
3321150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    const auto* oneof = field.containing_oneof();
3331150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    if (oneof != nullptr) {
3341150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      string camel_name = field.camelcase_name();
3351150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      camel_name[0] = toupper(camel_name[0]);
3361150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Print("if (msg.", oneof->name(), "_case() == ",
3371150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            GetQualifiedName(*oneof->containing_type()), "::k", camel_name,
3381150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            ") {");
3391150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Nest();
3401150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      AppendFieldValueAppend(field, false /* omit_default */,
3411150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower                             "msg." + name + "()");
3421150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Unnest();
3431150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      Print("}");
3441150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    } else {
3451150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower      AppendFieldValueAppend(field, true /* omit_default */,
3461150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower                             "msg." + name + "()");
3471150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    }
348df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
349df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
350df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
351df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendEnumFunctions(const EnumDescriptor& enum_d) {
352df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string sig = StrCat("const char* ", GetEnumNameFn(enum_d), "(\n    ",
353df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                            GetQualifiedName(enum_d), " value)");
354df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_);
355df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("// Enum text output for ", string(enum_d.full_name()));
356df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print(sig, ";");
357df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
358df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
359df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print(sig, " {");
360df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Nest().Print("switch (value) {").Nest();
361df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < enum_d.value_count(); ++i) {
362df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    const auto& value = *enum_d.value(i);
363df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("case ", value.number(), ": return \"", value.name(), "\";");
364df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
365df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("default: return \"\";");
366df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
367df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
368df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
369df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
370df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendParseMessageFunction(const Descriptor& md) {
371df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const bool map_append = (md.options().map_entry());
372df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  string sig;
373df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (!map_append) {
374df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    sig = StrCat("bool ProtoParseFromString(\n    const string& s,\n    ",
375df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                 GetQualifiedName(md), "* msg)");
376df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&header_).Print(sig, "\n        TF_MUST_USE_RESULT;");
377df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
378df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&cc_);
379df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print().Print(sig, " {").Nest();
380df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("msg->Clear();");
381df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("Scanner scanner(s);");
382df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("if (!internal::ProtoParseFromScanner(",
383df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower          "&scanner, false, false, msg)) return false;");
384df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("scanner.Eos();");
385df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("return scanner.GetResult();");
386df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Unnest().Print("}");
387df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
388df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
389df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Parse from scanner - the real work here.
390d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  sig = StrCat("bool ProtoParseFromScanner(",
391df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower               "\n    ::tensorflow::strings::Scanner* scanner, bool nested, "
392df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower               "bool close_curly,\n    ");
393df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const FieldDescriptor* key_type = nullptr;
394df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const FieldDescriptor* value_type = nullptr;
395df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (map_append) {
396df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    key_type = md.FindFieldByName("key");
397df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    value_type = md.FindFieldByName("value");
398df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(&sig, "::tensorflow::protobuf::Map<", GetCppClass(*key_type),
399df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower              ", ", GetCppClass(*value_type), ">* map)");
400df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else {
401df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    StrAppend(&sig, GetQualifiedName(md), "* msg)");
402df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
403d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
404d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (!map_append_signatures_included_.insert(sig).second) {
405d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    // signature for function to append to a map of this type has
406d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    // already been defined in this .cc file. Don't define it again.
407d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    return;
408d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
409d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
410d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (!map_append) {
411d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    SetOutput(&header_impl_).Print(sig, ";");
412d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
413df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
414df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
415df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("namespace internal {");
416d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  if (map_append) {
417d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower    Print("namespace {");
418d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  }
419df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print(sig, " {").Nest();
420df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (map_append) {
421df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print(GetCppClass(*key_type), " map_key;");
422df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("bool set_map_key = false;");
423df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print(GetCppClass(*value_type), " map_value;");
424df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("bool set_map_value = false;");
425df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
426df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("std::vector<bool> has_seen(", md.field_count(), ", false);");
427df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("while(true) {").Nest();
428df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("ProtoSpaceAndComments(scanner);");
429df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
430df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Emit success case
431df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (nested && (scanner->Peek() == (close_curly ? '}' : '>'))) {")
432df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      .Nest();
433df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("scanner->One(Scanner::ALL);");
434df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("ProtoSpaceAndComments(scanner);");
435df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (map_append) {
436df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("if (!set_map_key || !set_map_value) return false;");
437df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("(*map)[map_key] = map_value;");
438df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
439df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("return true;");
440df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}");
441df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
442df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (!nested && scanner->empty()) { return true; }");
443df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("scanner->RestartCapture()");
444df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("    .Many(Scanner::LETTER_DIGIT_UNDERSCORE)");
445df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("    .StopCapture();");
446df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("StringPiece identifier;");
447df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("if (!scanner->GetResult(nullptr, &identifier)) return false;");
448df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("bool parsed_colon = false;");
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;
637df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.field_count(); ++i) {
6381150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    fields.push_back(md.field(i));
6391150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  }
6401150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  std::sort(fields.begin(), fields.end(),
6411150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            [](const FieldDescriptor* left, const FieldDescriptor* right) {
6421150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower              return left->number() < right->number();
6431150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower            });
6441150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower
6451150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower  for (const FieldDescriptor* field : fields) {
646df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    SetOutput(&cc_);
6471150ce54376b01fdac3790f4906a5b34f5b7b65bA. Unique TensorFlower    AppendFieldAppend(*field);
648df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
649df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Unnest().Print("}").Print().Print("}  // namespace internal");
650df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
651df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
652df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AppendMessageFunctions(const Descriptor& md) {
653df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (md.options().map_entry()) {
654df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // The 'map entry' Message is not a user-visible message type.  Only its
655df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // parse function is created (and that actually parsed the whole Map, not
656df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // just the map entry). Printing of a map is done in the code generated for
657df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    // the containing message.
658df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendParseMessageFunction(md);
659df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    return;
660df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
661df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
662d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  // Recurse before adding the main message function, so that internal
663d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  // map_append functions are available before they are needed.
664df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.enum_type_count(); ++i) {
665df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendEnumFunctions(*md.enum_type(i));
666df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
667df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < md.nested_type_count(); ++i) {
668df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendMessageFunctions(*md.nested_type(i));
669df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
670d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower
671d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  AppendDebugStringFunctions(md);
672d111957918d2948c032c0093999d5a4ab1e698b0A. Unique TensorFlower  AppendParseMessageFunction(md);
673df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
674df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
675df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AddNamespaceToCurrentSection(const string& package, bool open) {
676df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
6774e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  std::vector<string> parts = {""};
6784e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  for (int i = 0; i < package.size(); ++i) {
6794e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    if (package[i] == '.') {
6804e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      parts.resize(parts.size() + 1);
6814e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    } else {
6824e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp      parts.back() += package[i];
6834e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp    }
6844e9a42b7d3764928bdb6625c26f2dbd8f0415834Andrew Harp  }
685df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (open) {
686df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    for (const auto& p : parts) {
687df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("namespace ", p, " {");
688df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
689df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  } else {
690df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    for (auto it = parts.rbegin(); it != parts.rend(); ++it) {
691df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      Print("}  // namespace ", *it);
692df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
693df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
694df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
695df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
696df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::AddHeadersToCurrentSection(const std::vector<string>& headers) {
697df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::vector<string> sorted = headers;
698df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::sort(sorted.begin(), sorted.end());
699df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (const auto& h : sorted) {
700df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("#include \"", h, "\"");
701df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
702df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
703df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
704df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Adds to <all_fd> and <all_d> with all descriptors recursively
705df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// reachable from the given descriptor.
706df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid GetAllFileDescriptorsFromFile(const FileDescriptor* fd,
707df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const FileDescriptor*>* all_fd,
708df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const Descriptor*>* all_d);
709df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
710df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// Adds to <all_fd> and <all_d> with all descriptors recursively
711df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower// reachable from the given descriptor.
712df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid GetAllFileDescriptorsFromMessage(const Descriptor* d,
713df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                      std::set<const FileDescriptor*>* all_fd,
714df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                      std::set<const Descriptor*>* all_d) {
715df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (!all_d->insert(d).second) return;
716df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  GetAllFileDescriptorsFromFile(d->file(), all_fd, all_d);
717df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < d->field_count(); ++i) {
718df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    auto* f = d->field(i);
719df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    switch (f->cpp_type()) {
720df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_INT32:
721df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_INT64:
722df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_UINT32:
723df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_UINT64:
724df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_DOUBLE:
725df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_FLOAT:
726df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_BOOL:
727df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_STRING:
728df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        break;
729df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_MESSAGE:
730df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        GetAllFileDescriptorsFromMessage(f->message_type(), all_fd, all_d);
731df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        break;
732df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      case FieldDescriptor::CPPTYPE_ENUM:
733df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        GetAllFileDescriptorsFromFile(f->enum_type()->file(), all_fd, all_d);
734df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower        break;
735df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
736df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
737df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < d->nested_type_count(); ++i) {
738df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    GetAllFileDescriptorsFromMessage(d->nested_type(i), all_fd, all_d);
739df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
740df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
741df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
742df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid GetAllFileDescriptorsFromFile(const FileDescriptor* fd,
743df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const FileDescriptor*>* all_fd,
744df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                   std::set<const Descriptor*>* all_d) {
745df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  if (!all_fd->insert(fd).second) return;
746df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < fd->message_type_count(); ++i) {
747df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    GetAllFileDescriptorsFromMessage(fd->message_type(i), all_fd, all_d);
748df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
749df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
750df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
751df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowervoid Generator::Generate(const FileDescriptor& fd) {
752df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // This does not emit code with proper proto2 semantics (e.g. it doesn't check
753df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // 'has' fields on non-messages), so check that only proto3 is passed.
754df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  CHECK_EQ(fd.syntax(), FileDescriptor::SYNTAX_PROTO3) << fd.name();
755df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
756df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  const string package = fd.package();
757df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::set<const FileDescriptor*> all_fd;
758df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::set<const Descriptor*> all_d;
759df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  GetAllFileDescriptorsFromFile(&fd, &all_fd, &all_d);
760df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
761df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  std::vector<string> headers;
762df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
763df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add header to header file.
764df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_);
765df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("// GENERATED FILE - DO NOT MODIFY");
766df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#ifndef ", GetHeaderGuard(fd, false /* impl */));
767df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#define ", GetHeaderGuard(fd, false /* impl */));
768df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
769df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  headers = {
770df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      GetProtoHeaderName(fd),
771df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/platform/macros.h"),
772df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/platform/protobuf.h"),
773df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/platform/types.h"),
774df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  };
775df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (const auto& h : headers) {
776df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    Print("#include \"", h, "\"");
777df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
778df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, true /* is_open */);
779df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
780df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add header to impl file.
781df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_);
782df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("// GENERATED FILE - DO NOT MODIFY");
783df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#ifndef ", GetHeaderGuard(fd, true /* impl */));
784df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("#define ", GetHeaderGuard(fd, true /* impl */));
785df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
786df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  headers = {
787df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      GetProtoTextHeaderName(fd, false /* impl */),
788df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_,
789df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower             "tensorflow/core/lib/strings/proto_text_util.h"),
790df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      StrCat(tf_header_prefix_, "tensorflow/core/lib/strings/scanner.h"),
791df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  };
792df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (const FileDescriptor* d : all_fd) {
793df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    if (d != &fd) {
794df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower      headers.push_back(GetProtoTextHeaderName(*d, true /* impl */));
795df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    }
796df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    headers.push_back(GetProtoHeaderName(*d));
797df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
7982d1c32eade41eaf9b9baf88fd5f5aa56bfed3dc0A. Unique TensorFlower  AddHeadersToCurrentSection(headers);
799df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, true /* is_open */);
800df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_).Print().Print("namespace internal {");
801df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
802df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add header to cc file.
803df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
804df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("// GENERATED FILE - DO NOT MODIFY");
805df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  headers = {GetProtoTextHeaderName(fd, true /* impl */)};
806df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddHeadersToCurrentSection(headers);
807df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print();
808df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("using ::tensorflow::strings::Scanner;");
809df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print("using ::tensorflow::strings::StrCat;");
810df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, true /* is_open */);
811df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
812df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add declarations and definitions.
813df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < fd.enum_type_count(); ++i) {
814df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendEnumFunctions(*fd.enum_type(i));
815df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
816df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  for (int i = 0; i < fd.message_type_count(); ++i) {
817df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower    AppendMessageFunctions(*fd.message_type(i));
818df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  }
819df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
820df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add footer to header file.
821df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_);
822df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, false /* is_open */);
823df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("#endif  // ", GetHeaderGuard(fd, false /* impl */));
824df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
825df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add footer to header impl file.
826df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&header_impl_).Print().Print("}  // namespace internal");
827df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, false /* is_open */);
828df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Print().Print("#endif  // ", GetHeaderGuard(fd, true /* impl */));
829df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
830df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  // Add footer to cc file.
831df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  SetOutput(&cc_);
832df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  AddNamespaceToCurrentSection(package, false /* is_open */);
833df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
834df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
835df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}  // namespace
836df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
837df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlowerProtoTextFunctionCode GetProtoTextFunctionCode(const FileDescriptor& fd,
838df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower                                               const string& tf_header_prefix) {
839df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  Generator gen(tf_header_prefix);
840df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  gen.Generate(fd);
841df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower  return gen.code();
842df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}
843df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower
844df15baa9b10a0b2d194181dff7ee14bff70d9b8fA. Unique TensorFlower}  // namespace tensorflow
845