35 #include <google/protobuf/io/printer.h>
39 #include <google/protobuf/stubs/logging.h>
40 #include <google/protobuf/stubs/common.h>
41 #include <google/protobuf/io/zero_copy_stream.h>
48 : variable_delimiter_(variable_delimiter),
53 at_start_of_line_(
true),
55 annotation_collector_(NULL) {}
58 AnnotationCollector* annotation_collector)
59 : variable_delimiter_(variable_delimiter),
64 at_start_of_line_(
true),
66 annotation_collector_(annotation_collector) {}
76 std::pair<size_t, size_t>*
range) {
77 std::map<std::string, std::pair<size_t, size_t> >::const_iterator
iter =
80 GOOGLE_LOG(DFATAL) <<
" Undefined variable in annotation: " << varname;
83 if (
iter->second.first >
iter->second.second) {
84 GOOGLE_LOG(DFATAL) <<
" Variable used for annotation used multiple times: "
94 const std::vector<int>&
path) {
99 std::pair<size_t, size_t>
begin,
end;
105 GOOGLE_LOG(DFATAL) <<
" Annotation has negative length from " << begin_varname
106 <<
" to " << end_varname;
113 void Printer::Print(
const std::map<std::string, std::string>& variables,
120 for (
int i = 0;
i <
size;
i++) {
121 if (
text[i] ==
'\n') {
142 GOOGLE_LOG(DFATAL) <<
" Unclosed variable name.";
148 if (varname.empty()) {
153 std::map<std::string, std::string>::const_iterator
iter =
154 variables.find(varname);
155 if (
iter == variables.end()) {
156 GOOGLE_LOG(DFATAL) <<
" Undefined variable: " << varname;
162 std::pair<std::map<std::string, std::pair<size_t, size_t> >
::iterator,
171 inserted.first->second = std::make_pair(1, 0);
190 GOOGLE_LOG(DFATAL) <<
" Outdent() without matching Indent().";
208 if (
size == 0)
return;
239 buffer_ =
reinterpret_cast<char*
>(void_buffer);
246 if (
size == 0)
return;
260 buffer_ =
reinterpret_cast<char*
>(void_buffer);
278 const std::map<std::string, std::string>& vars,
282 std::vector<AnnotationCollector::Annotation> annotations;
299 if (arg_index !=
static_cast<int>(
args.size())) {
302 if (!annotations.empty()) {
308 const std::vector<std::string>&
args,
309 const std::map<std::string, std::string>& vars,
const char*
format,
310 int* arg_index, std::vector<AnnotationCollector::Annotation>* annotations) {
327 if (
idx < 0 ||
static_cast<size_t>(
idx) >=
args.size()) {
330 if (
idx > *arg_index) {
331 GOOGLE_LOG(
FATAL) <<
"Annotation arg must be in correct order as given. Expected"
332 <<
" ${" << (*arg_index) + 1 <<
"$ got ${" <<
idx + 1 <<
"$.";
333 }
else if (
idx == *arg_index) {
339 }
else if (*
start ==
'}') {
341 if (annotations->empty()) {
344 auto&
a = annotations->back();
347 annotations->pop_back();
350 auto start_var =
start;
351 while (start_var <
end && *start_var ==
' ') start_var++;
352 if (start_var ==
end) {
356 while (start_var < end_var && *(end_var - 1) ==
' ') end_var--;
358 start_var,
static_cast<std::string::size_type
>(end_var - start_var)};
360 if (std::isdigit(var_name[0])) {
362 int idx = var_name[0] -
'1';
364 if (
static_cast<size_t>(
idx) >=
args.size()) {
367 if (
idx > *arg_index) {
368 GOOGLE_LOG(
FATAL) <<
"Arguments must be used in same order as given. Expected $"
369 << (*arg_index) + 1 <<
"$ got $" <<
idx + 1 <<
"$.";
370 }
else if (
idx == *arg_index) {
375 auto it = vars.find(var_name);
376 if (
it == vars.end()) {
384 if (sub.empty())
return format;