| 145 | } // namespace |
| 146 | |
| 147 | string RemoveDoc(const OpDef& op, const string& file_contents, |
| 148 | size_t start_location) { |
| 149 | // Look for a line starting with .Doc( after the REGISTER_OP. |
| 150 | const auto doc_start_location = file_contents.find(kDocStart, start_location); |
| 151 | const string format_error = strings::Printf( |
| 152 | "Could not find %s doc for removal. Make sure the doc is defined with " |
| 153 | "'%s' prefix and '%s' suffix or remove the doc manually.", |
| 154 | op.name().c_str(), kDocStart, kDocEnd); |
| 155 | if (doc_start_location == string::npos) { |
| 156 | std::cerr << format_error << std::endl; |
| 157 | LOG(ERROR) << "Didn't find doc start"; |
| 158 | return file_contents; |
| 159 | } |
| 160 | const auto doc_end_location = file_contents.find(kDocEnd, doc_start_location); |
| 161 | if (doc_end_location == string::npos) { |
| 162 | LOG(ERROR) << "Didn't find doc start"; |
| 163 | std::cerr << format_error << std::endl; |
| 164 | return file_contents; |
| 165 | } |
| 166 | |
| 167 | const auto doc_start_size = sizeof(kDocStart) - 1; |
| 168 | string doc_text = file_contents.substr( |
| 169 | doc_start_location + doc_start_size, |
| 170 | doc_end_location - doc_start_location - doc_start_size); |
| 171 | |
| 172 | // Make sure the doc text we found actually matches OpDef docs to |
| 173 | // avoid removing incorrect text. |
| 174 | if (!ValidateOpDocs(op, doc_text)) { |
| 175 | LOG(ERROR) << "Invalid doc: " << doc_text; |
| 176 | std::cerr << format_error << std::endl; |
| 177 | return file_contents; |
| 178 | } |
| 179 | // Remove .Doc call. |
| 180 | auto before_doc = file_contents.substr(0, doc_start_location); |
| 181 | absl::StripTrailingAsciiWhitespace(&before_doc); |
| 182 | return before_doc + |
| 183 | file_contents.substr(doc_end_location + sizeof(kDocEnd) - 1); |
| 184 | } |
| 185 | |
| 186 | namespace { |
| 187 | // Remove .Doc calls that follow REGISTER_OP calls for the given ops. |