Coverage Report

Created: 2026-04-12 06:27

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/flatbuffers/src/idl_gen_text.cpp
Line
Count
Source
1
/*
2
 * Copyright 2014 Google Inc. All rights reserved.
3
 *
4
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 * you may not use this file except in compliance with the License.
6
 * You may obtain a copy of the License at
7
 *
8
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 *
10
 * Unless required by applicable law or agreed to in writing, software
11
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 * See the License for the specific language governing permissions and
14
 * limitations under the License.
15
 */
16
17
// independent from idl_parser, since this code is not needed for most clients
18
#include "idl_gen_text.h"
19
20
#include <algorithm>
21
22
#include "flatbuffers/base.h"
23
#include "flatbuffers/code_generator.h"
24
#include "flatbuffers/flatbuffers.h"
25
#include "flatbuffers/flexbuffers.h"
26
#include "flatbuffers/idl.h"
27
#include "flatbuffers/util.h"
28
29
namespace flatbuffers {
30
31
struct PrintScalarTag {};
32
struct PrintPointerTag {};
33
template <typename T>
34
struct PrintTag {
35
  typedef PrintScalarTag type;
36
};
37
template <>
38
struct PrintTag<const void*> {
39
  typedef PrintPointerTag type;
40
};
41
42
struct JsonPrinter {
43
  // If indentation is less than 0, that indicates we don't want any newlines
44
  // either.
45
2.13M
  void AddNewLine() {
46
2.13M
    if (opts.indent_step >= 0) text += '\n';
47
2.13M
  }
48
49
1.73M
  void AddIndent(int ident) { text.append(ident, ' '); }
50
51
612k
  int Indent() const { return std::max(opts.indent_step, 0); }
52
53
  // Output an identifier with or without quotes depending on strictness.
54
708k
  void OutputIdentifier(const std::string& name) {
55
708k
    if (opts.strict_json) text += '\"';
56
708k
    text += name;
57
708k
    if (opts.strict_json) text += '\"';
58
708k
  }
59
60
  // Print (and its template specialization below for pointers) generate text
61
  // for a single FlatBuffer value into JSON format.
62
  // The general case for scalars:
63
  template <typename T>
64
785k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
785k
    if (IsBool(type.base_type)) {
66
35.3k
      text += val != 0 ? "true" : "false";
67
35.3k
      return;  // done
68
35.3k
    }
69
70
750k
    if (opts.output_enum_identifiers && type.enum_def) {
71
37.6k
      const auto& enum_def = *type.enum_def;
72
37.6k
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
19.0k
        text += '\"';
74
19.0k
        text += ev->name;
75
19.0k
        text += '\"';
76
19.0k
        return;  // done
77
19.0k
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
14.8k
        const auto entry_len = text.length();
79
14.8k
        const auto u64 = static_cast<uint64_t>(val);
80
14.8k
        uint64_t mask = 0;
81
14.8k
        text += '\"';
82
14.8k
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
59.5k
             it != e; ++it) {
84
44.6k
          auto f = (*it)->GetAsUInt64();
85
44.6k
          if (f & u64) {
86
19.3k
            mask |= f;
87
19.3k
            text += (*it)->name;
88
19.3k
            text += ' ';
89
19.3k
          }
90
44.6k
        }
91
        // Don't slice if (u64 != mask)
92
14.8k
        if (mask && (u64 == mask)) {
93
7.10k
          text[text.length() - 1] = '\"';
94
7.10k
          return;  // done
95
7.10k
        }
96
7.77k
        text.resize(entry_len);  // restore
97
7.77k
      }
98
      // print as numeric value
99
37.6k
    }
100
101
724k
    text += NumToString(val);
102
724k
    return;
103
750k
  }
void flatbuffers::JsonPrinter::PrintScalar<unsigned char>(unsigned char, flatbuffers::Type const&, int)
Line
Count
Source
64
84.0k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
84.0k
    if (IsBool(type.base_type)) {
66
35.3k
      text += val != 0 ? "true" : "false";
67
35.3k
      return;  // done
68
35.3k
    }
69
70
48.7k
    if (opts.output_enum_identifiers && type.enum_def) {
71
32.9k
      const auto& enum_def = *type.enum_def;
72
32.9k
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
17.7k
        text += '\"';
74
17.7k
        text += ev->name;
75
17.7k
        text += '\"';
76
17.7k
        return;  // done
77
17.7k
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
12.4k
        const auto entry_len = text.length();
79
12.4k
        const auto u64 = static_cast<uint64_t>(val);
80
12.4k
        uint64_t mask = 0;
81
12.4k
        text += '\"';
82
12.4k
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
49.7k
             it != e; ++it) {
84
37.2k
          auto f = (*it)->GetAsUInt64();
85
37.2k
          if (f & u64) {
86
16.5k
            mask |= f;
87
16.5k
            text += (*it)->name;
88
16.5k
            text += ' ';
89
16.5k
          }
90
37.2k
        }
91
        // Don't slice if (u64 != mask)
92
12.4k
        if (mask && (u64 == mask)) {
93
6.30k
          text[text.length() - 1] = '\"';
94
6.30k
          return;  // done
95
6.30k
        }
96
6.12k
        text.resize(entry_len);  // restore
97
6.12k
      }
98
      // print as numeric value
99
32.9k
    }
100
101
24.6k
    text += NumToString(val);
102
24.6k
    return;
103
48.7k
  }
void flatbuffers::JsonPrinter::PrintScalar<signed char>(signed char, flatbuffers::Type const&, int)
Line
Count
Source
64
31.2k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
31.2k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
31.2k
    if (opts.output_enum_identifiers && type.enum_def) {
71
1.71k
      const auto& enum_def = *type.enum_def;
72
1.71k
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
980
        text += '\"';
74
980
        text += ev->name;
75
980
        text += '\"';
76
980
        return;  // done
77
980
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
1.71k
    }
100
101
30.3k
    text += NumToString(val);
102
30.3k
    return;
103
31.2k
  }
void flatbuffers::JsonPrinter::PrintScalar<short>(short, flatbuffers::Type const&, int)
Line
Count
Source
64
35.7k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
35.7k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
35.7k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
35.7k
    text += NumToString(val);
102
35.7k
    return;
103
35.7k
  }
void flatbuffers::JsonPrinter::PrintScalar<unsigned short>(unsigned short, flatbuffers::Type const&, int)
Line
Count
Source
64
107k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
107k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
107k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
107k
    text += NumToString(val);
102
107k
    return;
103
107k
  }
void flatbuffers::JsonPrinter::PrintScalar<int>(int, flatbuffers::Type const&, int)
Line
Count
Source
64
44.1k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
44.1k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
44.1k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
44.1k
    text += NumToString(val);
102
44.1k
    return;
103
44.1k
  }
void flatbuffers::JsonPrinter::PrintScalar<unsigned int>(unsigned int, flatbuffers::Type const&, int)
Line
Count
Source
64
64.9k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
64.9k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
64.9k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
64.9k
    text += NumToString(val);
102
64.9k
    return;
103
64.9k
  }
void flatbuffers::JsonPrinter::PrintScalar<long>(long, flatbuffers::Type const&, int)
Line
Count
Source
64
94.5k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
94.5k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
94.5k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
94.5k
    text += NumToString(val);
102
94.5k
    return;
103
94.5k
  }
void flatbuffers::JsonPrinter::PrintScalar<unsigned long>(unsigned long, flatbuffers::Type const&, int)
Line
Count
Source
64
147k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
147k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
147k
    if (opts.output_enum_identifiers && type.enum_def) {
71
3.06k
      const auto& enum_def = *type.enum_def;
72
3.06k
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
284
        text += '\"';
74
284
        text += ev->name;
75
284
        text += '\"';
76
284
        return;  // done
77
2.77k
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
2.44k
        const auto entry_len = text.length();
79
2.44k
        const auto u64 = static_cast<uint64_t>(val);
80
2.44k
        uint64_t mask = 0;
81
2.44k
        text += '\"';
82
2.44k
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
9.79k
             it != e; ++it) {
84
7.34k
          auto f = (*it)->GetAsUInt64();
85
7.34k
          if (f & u64) {
86
2.82k
            mask |= f;
87
2.82k
            text += (*it)->name;
88
2.82k
            text += ' ';
89
2.82k
          }
90
7.34k
        }
91
        // Don't slice if (u64 != mask)
92
2.44k
        if (mask && (u64 == mask)) {
93
806
          text[text.length() - 1] = '\"';
94
806
          return;  // done
95
806
        }
96
1.64k
        text.resize(entry_len);  // restore
97
1.64k
      }
98
      // print as numeric value
99
3.06k
    }
100
101
146k
    text += NumToString(val);
102
146k
    return;
103
147k
  }
void flatbuffers::JsonPrinter::PrintScalar<float>(float, flatbuffers::Type const&, int)
Line
Count
Source
64
69.7k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
69.7k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
69.7k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
69.7k
    text += NumToString(val);
102
69.7k
    return;
103
69.7k
  }
void flatbuffers::JsonPrinter::PrintScalar<double>(double, flatbuffers::Type const&, int)
Line
Count
Source
64
105k
  void PrintScalar(T val, const Type& type, int /*indent*/) {
65
105k
    if (IsBool(type.base_type)) {
66
0
      text += val != 0 ? "true" : "false";
67
0
      return;  // done
68
0
    }
69
70
105k
    if (opts.output_enum_identifiers && type.enum_def) {
71
0
      const auto& enum_def = *type.enum_def;
72
0
      if (auto ev = enum_def.ReverseLookup(static_cast<int64_t>(val))) {
73
0
        text += '\"';
74
0
        text += ev->name;
75
0
        text += '\"';
76
0
        return;  // done
77
0
      } else if (val && enum_def.attributes.Lookup("bit_flags")) {
78
0
        const auto entry_len = text.length();
79
0
        const auto u64 = static_cast<uint64_t>(val);
80
0
        uint64_t mask = 0;
81
0
        text += '\"';
82
0
        for (auto it = enum_def.Vals().begin(), e = enum_def.Vals().end();
83
0
             it != e; ++it) {
84
0
          auto f = (*it)->GetAsUInt64();
85
0
          if (f & u64) {
86
0
            mask |= f;
87
0
            text += (*it)->name;
88
0
            text += ' ';
89
0
          }
90
0
        }
91
        // Don't slice if (u64 != mask)
92
0
        if (mask && (u64 == mask)) {
93
0
          text[text.length() - 1] = '\"';
94
0
          return;  // done
95
0
        }
96
0
        text.resize(entry_len);  // restore
97
0
      }
98
      // print as numeric value
99
0
    }
100
101
105k
    text += NumToString(val);
102
105k
    return;
103
105k
  }
104
105
516k
  void AddComma() {
106
516k
    if (!opts.protobuf_ascii_alike) text += ',';
107
516k
  }
108
109
  // Print a vector or an array of JSON values, comma seperated, wrapped in
110
  // "[]".
111
  template <typename Container, typename SizeT = typename Container::size_type>
112
  const char* PrintContainer(PrintScalarTag, const Container& c, SizeT size,
113
3.75k
                             const Type& type, int indent, const uint8_t*) {
114
3.75k
    const auto elem_indent = indent + Indent();
115
3.75k
    text += '[';
116
3.75k
    AddNewLine();
117
185k
    for (SizeT i = 0; i < size; i++) {
118
181k
      if (i) {
119
178k
        AddComma();
120
178k
        AddNewLine();
121
178k
      }
122
181k
      AddIndent(elem_indent);
123
181k
      PrintScalar(c[i], type, elem_indent);
124
181k
    }
125
3.75k
    AddNewLine();
126
3.75k
    AddIndent(indent);
127
3.75k
    text += ']';
128
3.75k
    return nullptr;
129
3.75k
  }
char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned char, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned char, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
113
1.56k
                             const Type& type, int indent, const uint8_t*) {
114
1.56k
    const auto elem_indent = indent + Indent();
115
1.56k
    text += '[';
116
1.56k
    AddNewLine();
117
36.3k
    for (SizeT i = 0; i < size; i++) {
118
34.8k
      if (i) {
119
33.7k
        AddComma();
120
33.7k
        AddNewLine();
121
33.7k
      }
122
34.8k
      AddIndent(elem_indent);
123
34.8k
      PrintScalar(c[i], type, elem_indent);
124
34.8k
    }
125
1.56k
    AddNewLine();
126
1.56k
    AddIndent(indent);
127
1.56k
    text += ']';
128
1.56k
    return nullptr;
129
1.56k
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<signed char, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<signed char, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<short, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<short, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned short, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned short, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<int, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<int, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned int, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned int, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<long, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<long, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
113
778
                             const Type& type, int indent, const uint8_t*) {
114
778
    const auto elem_indent = indent + Indent();
115
778
    text += '[';
116
778
    AddNewLine();
117
46.2k
    for (SizeT i = 0; i < size; i++) {
118
45.4k
      if (i) {
119
44.9k
        AddComma();
120
44.9k
        AddNewLine();
121
44.9k
      }
122
45.4k
      AddIndent(elem_indent);
123
45.4k
      PrintScalar(c[i], type, elem_indent);
124
45.4k
    }
125
778
    AddNewLine();
126
778
    AddIndent(indent);
127
778
    text += ']';
128
778
    return nullptr;
129
778
  }
char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<unsigned long, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<unsigned long, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
113
768
                             const Type& type, int indent, const uint8_t*) {
114
768
    const auto elem_indent = indent + Indent();
115
768
    text += '[';
116
768
    AddNewLine();
117
44.3k
    for (SizeT i = 0; i < size; i++) {
118
43.5k
      if (i) {
119
42.9k
        AddComma();
120
42.9k
        AddNewLine();
121
42.9k
      }
122
43.5k
      AddIndent(elem_indent);
123
43.5k
      PrintScalar(c[i], type, elem_indent);
124
43.5k
    }
125
768
    AddNewLine();
126
768
    AddIndent(indent);
127
768
    text += ']';
128
768
    return nullptr;
129
768
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<float, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<float, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<double, unsigned int>, unsigned int>(flatbuffers::PrintScalarTag, flatbuffers::Vector<double, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
113
644
                             const Type& type, int indent, const uint8_t*) {
114
644
    const auto elem_indent = indent + Indent();
115
644
    text += '[';
116
644
    AddNewLine();
117
58.2k
    for (SizeT i = 0; i < size; i++) {
118
57.5k
      if (i) {
119
57.1k
        AddComma();
120
57.1k
        AddNewLine();
121
57.1k
      }
122
57.5k
      AddIndent(elem_indent);
123
57.5k
      PrintScalar(c[i], type, elem_indent);
124
57.5k
    }
125
644
    AddNewLine();
126
644
    AddIndent(indent);
127
644
    text += ']';
128
644
    return nullptr;
129
644
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned char, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned char, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<signed char, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<signed char, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<short, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<short, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned short, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned short, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<int, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<int, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned int, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned int, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<long, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<long, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<unsigned long, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<unsigned long, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<float, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<float, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<double, (unsigned short)65535>, unsigned short>(flatbuffers::PrintScalarTag, flatbuffers::Array<double, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
130
131
  // Print a vector or an array of JSON values, comma seperated, wrapped in
132
  // "[]".
133
  template <typename Container, typename SizeT = typename Container::size_type>
134
  const char* PrintContainer(PrintPointerTag, const Container& c, SizeT size,
135
                             const Type& type, int indent,
136
6.48k
                             const uint8_t* prev_val) {
137
6.48k
    const auto is_struct = IsStruct(type);
138
6.48k
    const auto elem_indent = indent + Indent();
139
6.48k
    text += '[';
140
6.48k
    AddNewLine();
141
240k
    for (SizeT i = 0; i < size; i++) {
142
234k
      if (i) {
143
230k
        AddComma();
144
230k
        AddNewLine();
145
230k
      }
146
234k
      AddIndent(elem_indent);
147
234k
      auto ptr = is_struct ? reinterpret_cast<const void*>(
148
13.7k
                                 c.Data() + type.struct_def->bytesize * i)
149
234k
                           : c[i];
150
234k
      auto err = PrintOffset(ptr, type, elem_indent, prev_val,
151
234k
                             static_cast<soffset_t>(i));
152
234k
      if (err) return err;
153
234k
    }
154
6.48k
    AddNewLine();
155
6.48k
    AddIndent(indent);
156
6.48k
    text += ']';
157
6.48k
    return nullptr;
158
6.48k
  }
char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<flatbuffers::Offset<void>, unsigned int>, unsigned int>(flatbuffers::PrintPointerTag, flatbuffers::Vector<flatbuffers::Offset<void>, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
136
6.48k
                             const uint8_t* prev_val) {
137
6.48k
    const auto is_struct = IsStruct(type);
138
6.48k
    const auto elem_indent = indent + Indent();
139
6.48k
    text += '[';
140
6.48k
    AddNewLine();
141
240k
    for (SizeT i = 0; i < size; i++) {
142
234k
      if (i) {
143
230k
        AddComma();
144
230k
        AddNewLine();
145
230k
      }
146
234k
      AddIndent(elem_indent);
147
234k
      auto ptr = is_struct ? reinterpret_cast<const void*>(
148
13.7k
                                 c.Data() + type.struct_def->bytesize * i)
149
234k
                           : c[i];
150
234k
      auto err = PrintOffset(ptr, type, elem_indent, prev_val,
151
234k
                             static_cast<soffset_t>(i));
152
234k
      if (err) return err;
153
234k
    }
154
6.48k
    AddNewLine();
155
6.48k
    AddIndent(indent);
156
6.48k
    text += ']';
157
6.48k
    return nullptr;
158
6.48k
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Vector<flatbuffers::Offset64<void>, unsigned int>, unsigned int>(flatbuffers::PrintPointerTag, flatbuffers::Vector<flatbuffers::Offset64<void>, unsigned int> const&, unsigned int, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<flatbuffers::Offset<void>, (unsigned short)65535>, unsigned short>(flatbuffers::PrintPointerTag, flatbuffers::Array<flatbuffers::Offset<void>, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintContainer<flatbuffers::Array<flatbuffers::Offset64<void>, (unsigned short)65535>, unsigned short>(flatbuffers::PrintPointerTag, flatbuffers::Array<flatbuffers::Offset64<void>, (unsigned short)65535> const&, unsigned short, flatbuffers::Type const&, int, unsigned char const*)
159
160
  template <typename T, typename SizeT = uoffset_t>
161
  const char* PrintVector(const void* val, const Type& type, int indent,
162
10.2k
                          const uint8_t* prev_val) {
163
10.2k
    typedef Vector<T, SizeT> Container;
164
10.2k
    typedef typename PrintTag<typename Container::return_type>::type tag;
165
10.2k
    auto& vec = *reinterpret_cast<const Container*>(val);
166
10.2k
    return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
167
10.2k
                                     prev_val);
168
10.2k
  }
char const* flatbuffers::JsonPrinter::PrintVector<unsigned char, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
162
1.56k
                          const uint8_t* prev_val) {
163
1.56k
    typedef Vector<T, SizeT> Container;
164
1.56k
    typedef typename PrintTag<typename Container::return_type>::type tag;
165
1.56k
    auto& vec = *reinterpret_cast<const Container*>(val);
166
1.56k
    return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
167
1.56k
                                     prev_val);
168
1.56k
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<signed char, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<short, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<unsigned short, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<int, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<unsigned int, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
char const* flatbuffers::JsonPrinter::PrintVector<long, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
162
778
                          const uint8_t* prev_val) {
163
778
    typedef Vector<T, SizeT> Container;
164
778
    typedef typename PrintTag<typename Container::return_type>::type tag;
165
778
    auto& vec = *reinterpret_cast<const Container*>(val);
166
778
    return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
167
778
                                     prev_val);
168
778
  }
char const* flatbuffers::JsonPrinter::PrintVector<unsigned long, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
162
768
                          const uint8_t* prev_val) {
163
768
    typedef Vector<T, SizeT> Container;
164
768
    typedef typename PrintTag<typename Container::return_type>::type tag;
165
768
    auto& vec = *reinterpret_cast<const Container*>(val);
166
768
    return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
167
768
                                     prev_val);
168
768
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<float, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
char const* flatbuffers::JsonPrinter::PrintVector<double, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
162
644
                          const uint8_t* prev_val) {
163
644
    typedef Vector<T, SizeT> Container;
164
644
    typedef typename PrintTag<typename Container::return_type>::type tag;
165
644
    auto& vec = *reinterpret_cast<const Container*>(val);
166
644
    return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
167
644
                                     prev_val);
168
644
  }
char const* flatbuffers::JsonPrinter::PrintVector<flatbuffers::Offset<void>, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
Line
Count
Source
162
6.48k
                          const uint8_t* prev_val) {
163
6.48k
    typedef Vector<T, SizeT> Container;
164
6.48k
    typedef typename PrintTag<typename Container::return_type>::type tag;
165
6.48k
    auto& vec = *reinterpret_cast<const Container*>(val);
166
6.48k
    return PrintContainer<Container>(tag(), vec, vec.size(), type, indent,
167
6.48k
                                     prev_val);
168
6.48k
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintVector<flatbuffers::Offset64<void>, unsigned int>(void const*, flatbuffers::Type const&, int, unsigned char const*)
169
170
  // Print an array a sequence of JSON values, comma separated, wrapped in "[]".
171
  template <typename T>
172
  const char* PrintArray(const void* val, uint16_t size, const Type& type,
173
174
0
                         int indent) {
175
0
    typedef Array<T, 0xFFFF> Container;
176
0
    typedef typename PrintTag<typename Container::return_type>::type tag;
177
0
    auto& arr = *reinterpret_cast<const Container*>(val);
178
0
    return PrintContainer<Container>(tag(), arr, size, type, indent, nullptr);
179
0
  }
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned char>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<signed char>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<short>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned short>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<int>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned int>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<long>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<unsigned long>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<float>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<double>(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<flatbuffers::Offset<void> >(void const*, unsigned short, flatbuffers::Type const&, int)
Unexecuted instantiation: char const* flatbuffers::JsonPrinter::PrintArray<flatbuffers::Offset64<void> >(void const*, unsigned short, flatbuffers::Type const&, int)
180
181
  const char* PrintOffset(const void* val, const Type& type, int indent,
182
322k
                          const uint8_t* prev_val, soffset_t vector_index) {
183
322k
    switch (type.base_type) {
184
1.85k
      case BASE_TYPE_UNION: {
185
        // If this assert hits, you have an corrupt buffer, a union type field
186
        // was not present or was out of range.
187
1.85k
        FLATBUFFERS_ASSERT(prev_val);
188
1.85k
        auto union_type_byte = *prev_val;  // Always a uint8_t.
189
1.85k
        if (vector_index >= 0) {
190
0
          auto type_vec = reinterpret_cast<const Vector<uint8_t>*>(
191
0
              prev_val + ReadScalar<uoffset_t>(prev_val));
192
0
          union_type_byte = type_vec->Get(static_cast<uoffset_t>(vector_index));
193
0
        }
194
1.85k
        auto enum_val = type.enum_def->ReverseLookup(union_type_byte, true);
195
1.85k
        if (enum_val) {
196
1.85k
          return PrintOffset(val, enum_val->union_type, indent, nullptr, -1);
197
1.85k
        } else {
198
0
          return "unknown enum value";
199
0
        }
200
1.85k
      }
201
197k
      case BASE_TYPE_STRUCT:
202
197k
        return GenStruct(*type.struct_def, reinterpret_cast<const Table*>(val),
203
197k
                         indent);
204
113k
      case BASE_TYPE_STRING: {
205
113k
        auto s = reinterpret_cast<const String*>(val);
206
113k
        bool ok = EscapeString(s->c_str(), s->size(), &text,
207
113k
                               opts.allow_non_utf8, opts.natural_utf8);
208
113k
        return ok ? nullptr : "string contains non-utf8 bytes";
209
1.85k
      }
210
10.2k
      case BASE_TYPE_VECTOR: {
211
10.2k
        const auto vec_type = type.VectorType();
212
        // Call PrintVector above specifically for each element type:
213
        // clang-format off
214
10.2k
        switch (vec_type.base_type) {
215
0
        #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
216
10.2k
          case BASE_TYPE_ ## ENUM: { \
217
10.2k
            auto err = PrintVector<CTYPE>(val, vec_type, indent, prev_val); \
218
10.2k
            if (err) return err; \
219
10.2k
            break; }
220
10.2k
          FLATBUFFERS_GEN_TYPES(FLATBUFFERS_TD)
221
10.2k
        #undef FLATBUFFERS_TD
222
10.2k
        }
223
        // clang-format on
224
10.2k
        return nullptr;
225
10.2k
      }
226
0
      case BASE_TYPE_ARRAY: {
227
0
        const auto vec_type = type.VectorType();
228
        // Call PrintArray above specifically for each element type:
229
        // clang-format off
230
0
        switch (vec_type.base_type) {
231
0
        #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
232
0
          case BASE_TYPE_ ## ENUM: { \
233
0
            auto err = PrintArray<CTYPE>(val, type.fixed_length, vec_type, indent); \
234
0
            if (err) return err; \
235
0
            break; }
236
0
            FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
237
              // Arrays of scalars or structs are only possible.
238
0
              FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
239
0
        #undef FLATBUFFERS_TD
240
0
          case BASE_TYPE_ARRAY: FLATBUFFERS_ASSERT(0);
241
0
        }
242
        // clang-format on
243
0
        return nullptr;
244
0
      }
245
0
      default:
246
0
        FLATBUFFERS_ASSERT(0);
247
0
        return "unknown type";
248
322k
    }
249
322k
  }
250
251
  template <typename T>
252
542k
  static T GetFieldDefault(const FieldDef& fd) {
253
542k
    T val{};
254
542k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
542k
    (void)check;
256
542k
    FLATBUFFERS_ASSERT(check);
257
542k
    return val;
258
542k
  }
unsigned char flatbuffers::JsonPrinter::GetFieldDefault<unsigned char>(flatbuffers::FieldDef const&)
Line
Count
Source
252
44.4k
  static T GetFieldDefault(const FieldDef& fd) {
253
44.4k
    T val{};
254
44.4k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
44.4k
    (void)check;
256
44.4k
    FLATBUFFERS_ASSERT(check);
257
44.4k
    return val;
258
44.4k
  }
signed char flatbuffers::JsonPrinter::GetFieldDefault<signed char>(flatbuffers::FieldDef const&)
Line
Count
Source
252
25.3k
  static T GetFieldDefault(const FieldDef& fd) {
253
25.3k
    T val{};
254
25.3k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
25.3k
    (void)check;
256
25.3k
    FLATBUFFERS_ASSERT(check);
257
25.3k
    return val;
258
25.3k
  }
short flatbuffers::JsonPrinter::GetFieldDefault<short>(flatbuffers::FieldDef const&)
Line
Count
Source
252
29.8k
  static T GetFieldDefault(const FieldDef& fd) {
253
29.8k
    T val{};
254
29.8k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
29.8k
    (void)check;
256
29.8k
    FLATBUFFERS_ASSERT(check);
257
29.8k
    return val;
258
29.8k
  }
unsigned short flatbuffers::JsonPrinter::GetFieldDefault<unsigned short>(flatbuffers::FieldDef const&)
Line
Count
Source
252
107k
  static T GetFieldDefault(const FieldDef& fd) {
253
107k
    T val{};
254
107k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
107k
    (void)check;
256
107k
    FLATBUFFERS_ASSERT(check);
257
107k
    return val;
258
107k
  }
int flatbuffers::JsonPrinter::GetFieldDefault<int>(flatbuffers::FieldDef const&)
Line
Count
Source
252
44.1k
  static T GetFieldDefault(const FieldDef& fd) {
253
44.1k
    T val{};
254
44.1k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
44.1k
    (void)check;
256
44.1k
    FLATBUFFERS_ASSERT(check);
257
44.1k
    return val;
258
44.1k
  }
unsigned int flatbuffers::JsonPrinter::GetFieldDefault<unsigned int>(flatbuffers::FieldDef const&)
Line
Count
Source
252
39.0k
  static T GetFieldDefault(const FieldDef& fd) {
253
39.0k
    T val{};
254
39.0k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
39.0k
    (void)check;
256
39.0k
    FLATBUFFERS_ASSERT(check);
257
39.0k
    return val;
258
39.0k
  }
long flatbuffers::JsonPrinter::GetFieldDefault<long>(flatbuffers::FieldDef const&)
Line
Count
Source
252
49.0k
  static T GetFieldDefault(const FieldDef& fd) {
253
49.0k
    T val{};
254
49.0k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
49.0k
    (void)check;
256
49.0k
    FLATBUFFERS_ASSERT(check);
257
49.0k
    return val;
258
49.0k
  }
unsigned long flatbuffers::JsonPrinter::GetFieldDefault<unsigned long>(flatbuffers::FieldDef const&)
Line
Count
Source
252
103k
  static T GetFieldDefault(const FieldDef& fd) {
253
103k
    T val{};
254
103k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
103k
    (void)check;
256
103k
    FLATBUFFERS_ASSERT(check);
257
103k
    return val;
258
103k
  }
float flatbuffers::JsonPrinter::GetFieldDefault<float>(flatbuffers::FieldDef const&)
Line
Count
Source
252
55.2k
  static T GetFieldDefault(const FieldDef& fd) {
253
55.2k
    T val{};
254
55.2k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
55.2k
    (void)check;
256
55.2k
    FLATBUFFERS_ASSERT(check);
257
55.2k
    return val;
258
55.2k
  }
double flatbuffers::JsonPrinter::GetFieldDefault<double>(flatbuffers::FieldDef const&)
Line
Count
Source
252
43.5k
  static T GetFieldDefault(const FieldDef& fd) {
253
43.5k
    T val{};
254
43.5k
    auto check = StringToNumber(fd.value.constant.c_str(), &val);
255
43.5k
    (void)check;
256
43.5k
    FLATBUFFERS_ASSERT(check);
257
43.5k
    return val;
258
43.5k
  }
259
260
  // Generate text for a scalar field.
261
  template <typename T>
262
  void GenField(const FieldDef& fd, const Table* table, bool fixed,
263
604k
                int indent) {
264
604k
    if (fixed) {
265
62.0k
      PrintScalar(
266
62.0k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
62.0k
          fd.value.type, indent);
268
542k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
542k
    } else {
276
542k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
542k
                  fd.value.type, indent);
278
542k
    }
279
604k
  }
void flatbuffers::JsonPrinter::GenField<unsigned char>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
49.2k
                int indent) {
264
49.2k
    if (fixed) {
265
4.84k
      PrintScalar(
266
4.84k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
4.84k
          fd.value.type, indent);
268
44.4k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
44.4k
    } else {
276
44.4k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
44.4k
                  fd.value.type, indent);
278
44.4k
    }
279
49.2k
  }
void flatbuffers::JsonPrinter::GenField<signed char>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
31.2k
                int indent) {
264
31.2k
    if (fixed) {
265
5.94k
      PrintScalar(
266
5.94k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
5.94k
          fd.value.type, indent);
268
25.3k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
25.3k
    } else {
276
25.3k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
25.3k
                  fd.value.type, indent);
278
25.3k
    }
279
31.2k
  }
void flatbuffers::JsonPrinter::GenField<short>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
35.7k
                int indent) {
264
35.7k
    if (fixed) {
265
5.94k
      PrintScalar(
266
5.94k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
5.94k
          fd.value.type, indent);
268
29.8k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
29.8k
    } else {
276
29.8k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
29.8k
                  fd.value.type, indent);
278
29.8k
    }
279
35.7k
  }
void flatbuffers::JsonPrinter::GenField<unsigned short>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
107k
                int indent) {
264
107k
    if (fixed) {
265
0
      PrintScalar(
266
0
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
0
          fd.value.type, indent);
268
107k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
107k
    } else {
276
107k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
107k
                  fd.value.type, indent);
278
107k
    }
279
107k
  }
void flatbuffers::JsonPrinter::GenField<int>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
44.1k
                int indent) {
264
44.1k
    if (fixed) {
265
0
      PrintScalar(
266
0
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
0
          fd.value.type, indent);
268
44.1k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
44.1k
    } else {
276
44.1k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
44.1k
                  fd.value.type, indent);
278
44.1k
    }
279
44.1k
  }
void flatbuffers::JsonPrinter::GenField<unsigned int>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
64.9k
                int indent) {
264
64.9k
    if (fixed) {
265
25.9k
      PrintScalar(
266
25.9k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
25.9k
          fd.value.type, indent);
268
39.0k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
39.0k
    } else {
276
39.0k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
39.0k
                  fd.value.type, indent);
278
39.0k
    }
279
64.9k
  }
void flatbuffers::JsonPrinter::GenField<long>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
49.0k
                int indent) {
264
49.0k
    if (fixed) {
265
0
      PrintScalar(
266
0
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
0
          fd.value.type, indent);
268
49.0k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
49.0k
    } else {
276
49.0k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
49.0k
                  fd.value.type, indent);
278
49.0k
    }
279
49.0k
  }
void flatbuffers::JsonPrinter::GenField<unsigned long>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
103k
                int indent) {
264
103k
    if (fixed) {
265
0
      PrintScalar(
266
0
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
0
          fd.value.type, indent);
268
103k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
103k
    } else {
276
103k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
103k
                  fd.value.type, indent);
278
103k
    }
279
103k
  }
void flatbuffers::JsonPrinter::GenField<float>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
69.7k
                int indent) {
264
69.7k
    if (fixed) {
265
14.5k
      PrintScalar(
266
14.5k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
14.5k
          fd.value.type, indent);
268
55.2k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
55.2k
    } else {
276
55.2k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
55.2k
                  fd.value.type, indent);
278
55.2k
    }
279
69.7k
  }
void flatbuffers::JsonPrinter::GenField<double>(flatbuffers::FieldDef const&, flatbuffers::Table const*, bool, int)
Line
Count
Source
263
48.3k
                int indent) {
264
48.3k
    if (fixed) {
265
4.84k
      PrintScalar(
266
4.84k
          reinterpret_cast<const Struct*>(table)->GetField<T>(fd.value.offset),
267
4.84k
          fd.value.type, indent);
268
43.5k
    } else if (fd.IsOptional()) {
269
0
      auto opt = table->GetOptional<T, T>(fd.value.offset);
270
0
      if (opt) {
271
0
        PrintScalar(*opt, fd.value.type, indent);
272
0
      } else {
273
0
        text += "null";
274
0
      }
275
43.5k
    } else {
276
43.5k
      PrintScalar(table->GetField<T>(fd.value.offset, GetFieldDefault<T>(fd)),
277
43.5k
                  fd.value.type, indent);
278
43.5k
    }
279
48.3k
  }
280
281
  // Generate text for non-scalar field.
282
  const char* GenFieldOffset(const FieldDef& fd, const Table* table, bool fixed,
283
103k
                             int indent, const uint8_t* prev_val) {
284
103k
    const void* val = nullptr;
285
103k
    if (fixed) {
286
      // The only non-scalar fields in structs are structs or arrays.
287
4.84k
      FLATBUFFERS_ASSERT(IsStruct(fd.value.type) || IsArray(fd.value.type));
288
4.84k
      val = reinterpret_cast<const Struct*>(table)->GetStruct<const void*>(
289
4.84k
          fd.value.offset);
290
99.0k
    } else if (fd.flexbuffer && opts.json_nested_flexbuffers) {
291
      // We could verify this FlexBuffer before access, but since this sits
292
      // inside a FlatBuffer that we don't know wether it has been verified or
293
      // not, there is little point making this part safer than the parent..
294
      // The caller should really be verifying the whole.
295
      // If the whole buffer is corrupt, we likely crash before we even get
296
      // here.
297
11.1k
      auto vec = table->GetPointer<const Vector<uint8_t>*>(fd.value.offset);
298
11.1k
      auto root = flexbuffers::GetRoot(vec->data(), vec->size());
299
11.1k
      root.ToString(true, opts.strict_json, text);
300
11.1k
      return nullptr;
301
87.8k
    } else if (fd.nested_flatbuffer && opts.json_nested_flatbuffers) {
302
6.49k
      auto vec = table->GetPointer<const Vector<uint8_t>*>(fd.value.offset);
303
6.49k
      auto root = GetRoot<Table>(vec->data());
304
6.49k
      return GenStruct(*fd.nested_flatbuffer, root, indent);
305
81.3k
    } else {
306
81.3k
      val = IsStruct(fd.value.type)
307
81.3k
                ? table->GetStruct<const void*>(fd.value.offset)
308
81.3k
                : table->GetPointer<const void*>(fd.value.offset);
309
81.3k
    }
310
86.2k
    return PrintOffset(val, fd.value.type, indent, prev_val, -1);
311
103k
  }
312
313
  // Generate text for a struct or table, values separated by commas, indented,
314
  // and bracketed by "{}"
315
  const char* GenStruct(const StructDef& struct_def, const Table* table,
316
601k
                        int indent) {
317
601k
    text += '{';
318
601k
    int fieldout = 0;
319
601k
    const uint8_t* prev_val = nullptr;
320
601k
    const auto elem_indent = indent + Indent();
321
601k
    for (auto it = struct_def.fields.vec.begin();
322
5.01M
         it != struct_def.fields.vec.end(); ++it) {
323
4.41M
      FieldDef& fd = **it;
324
4.41M
      auto is_present = struct_def.fixed || table->CheckField(fd.value.offset);
325
4.41M
      auto output_anyway = (opts.output_default_scalars_in_json || fd.key) &&
326
589k
                           IsScalar(fd.value.type.base_type) && !fd.deprecated;
327
4.41M
      if (is_present || output_anyway) {
328
708k
        if (fieldout++) {
329
107k
          AddComma();
330
107k
        }
331
708k
        AddNewLine();
332
708k
        AddIndent(elem_indent);
333
708k
        OutputIdentifier(fd.name);
334
708k
        if (!opts.protobuf_ascii_alike ||
335
0
            (fd.value.type.base_type != BASE_TYPE_STRUCT &&
336
0
             fd.value.type.base_type != BASE_TYPE_VECTOR))
337
708k
          text += ':';
338
708k
        text += ' ';
339
        // clang-format off
340
708k
        switch (fd.value.type.base_type) {
341
0
        #define FLATBUFFERS_TD(ENUM, IDLTYPE, CTYPE, ...) \
342
604k
          case BASE_TYPE_ ## ENUM: { \
343
604k
            GenField<CTYPE>(fd, table, struct_def.fixed, elem_indent); \
344
604k
            break; }
345
604k
            FLATBUFFERS_GEN_TYPES_SCALAR(FLATBUFFERS_TD)
346
0
        #undef FLATBUFFERS_TD
347
        // Generate drop-thru case statements for all pointer types:
348
0
        #define FLATBUFFERS_TD(ENUM, ...) \
349
545k
          case BASE_TYPE_ ## ENUM:
350
441k
              FLATBUFFERS_GEN_TYPES_POINTER(FLATBUFFERS_TD)
351
441k
              FLATBUFFERS_GEN_TYPE_ARRAY(FLATBUFFERS_TD)
352
103k
        #undef FLATBUFFERS_TD
353
103k
            {
354
103k
              auto err = GenFieldOffset(fd, table, struct_def.fixed, elem_indent, prev_val);
355
103k
              if (err) return err;
356
103k
              break;
357
103k
            }
358
708k
        }
359
        // clang-format on
360
        // Track prev val for use with union types.
361
708k
        if (struct_def.fixed) {
362
66.8k
          prev_val = reinterpret_cast<const uint8_t*>(table) + fd.value.offset;
363
641k
        } else {
364
641k
          prev_val = table->GetAddressOf(fd.value.offset);
365
641k
        }
366
708k
      }
367
4.41M
    }
368
601k
    AddNewLine();
369
601k
    AddIndent(indent);
370
601k
    text += '}';
371
601k
    return nullptr;
372
601k
  }
373
374
  JsonPrinter(const Parser& parser, std::string& dest)
375
398k
      : opts(parser.opts), text(dest) {
376
398k
    text.reserve(1024);  // Reduce amount of inevitable reallocs.
377
398k
  }
378
379
  const IDLOptions& opts;
380
  std::string& text;
381
};
382
383
static const char* GenerateTextImpl(const Parser& parser, const Table* table,
384
                                    const StructDef& struct_def,
385
398k
                                    std::string* _text) {
386
398k
  JsonPrinter printer(parser, *_text);
387
398k
  auto err = printer.GenStruct(struct_def, table, 0);
388
398k
  if (err) return err;
389
398k
  printer.AddNewLine();
390
398k
  return nullptr;
391
398k
}
392
393
// Generate a text representation of a flatbuffer in JSON format.
394
// Deprecated: please use `GenTextFromTable`
395
bool GenerateTextFromTable(const Parser& parser, const void* table,
396
0
                           const std::string& table_name, std::string* _text) {
397
0
  return GenTextFromTable(parser, table, table_name, _text) != nullptr;
398
0
}
399
400
// Generate a text representation of a flatbuffer in JSON format.
401
const char* GenTextFromTable(const Parser& parser, const void* table,
402
                             const std::string& table_name,
403
0
                             std::string* _text) {
404
0
  auto struct_def = parser.LookupStruct(table_name);
405
0
  if (struct_def == nullptr) {
406
0
    return "unknown struct";
407
0
  }
408
0
  auto root = static_cast<const Table*>(table);
409
0
  return GenerateTextImpl(parser, root, *struct_def, _text);
410
0
}
411
412
// Deprecated: please use `GenText`
413
const char* GenerateText(const Parser& parser, const void* flatbuffer,
414
0
                         std::string* _text) {
415
0
  return GenText(parser, flatbuffer, _text);
416
0
}
417
418
// Generate a text representation of a flatbuffer in JSON format.
419
const char* GenText(const Parser& parser, const void* flatbuffer,
420
398k
                    std::string* _text) {
421
398k
  FLATBUFFERS_ASSERT(parser.root_struct_def_);  // call SetRootType()
422
398k
  auto root = parser.opts.size_prefixed ? GetSizePrefixedRoot<Table>(flatbuffer)
423
398k
                                        : GetRoot<Table>(flatbuffer);
424
398k
  return GenerateTextImpl(parser, root, *parser.root_struct_def_, _text);
425
398k
}
426
427
static std::string TextFileName(const std::string& path,
428
0
                                const std::string& file_name) {
429
0
  return path + file_name + ".json";
430
0
}
431
432
// Deprecated: please use `GenTextFile`
433
const char* GenerateTextFile(const Parser& parser, const std::string& path,
434
0
                             const std::string& file_name) {
435
0
  return GenTextFile(parser, path, file_name);
436
0
}
437
438
const char* GenTextFile(const Parser& parser, const std::string& path,
439
0
                        const std::string& file_name) {
440
0
  if (parser.opts.use_flexbuffers) {
441
0
    std::string json;
442
0
    parser.flex_root_.ToString(true, parser.opts.strict_json, json);
443
0
    return parser.opts.file_saver->SaveFile(
444
0
               TextFileName(path, file_name).c_str(), json.c_str(), json.size(),
445
0
               true)
446
0
               ? nullptr
447
0
               : "SaveFile failed";
448
0
  }
449
0
  if (!parser.builder_.GetSize() || !parser.root_struct_def_) return nullptr;
450
0
  std::string text;
451
0
  auto err = GenText(parser, parser.builder_.GetBufferPointer(), &text);
452
0
  if (err) return err;
453
0
  return parser.opts.file_saver->SaveFile(TextFileName(path, file_name).c_str(),
454
0
                                          text, false)
455
0
             ? nullptr
456
0
             : "SaveFile failed";
457
0
}
458
459
static std::string TextMakeRule(const Parser& parser, const std::string& path,
460
0
                                const std::string& file_name) {
461
0
  if (!parser.builder_.GetSize() || !parser.root_struct_def_) return "";
462
0
  std::string filebase =
463
0
      flatbuffers::StripPath(flatbuffers::StripExtension(file_name));
464
0
  std::string make_rule = TextFileName(path, filebase) + ": " + file_name;
465
0
  auto included_files =
466
0
      parser.GetIncludedFilesRecursive(parser.root_struct_def_->file);
467
0
  for (auto it = included_files.begin(); it != included_files.end(); ++it) {
468
0
    make_rule += " " + *it;
469
0
  }
470
0
  return make_rule;
471
0
}
472
473
namespace {
474
475
class TextCodeGenerator : public CodeGenerator {
476
 public:
477
  Status GenerateCode(const Parser& parser, const std::string& path,
478
0
                      const std::string& filename) override {
479
0
    auto err = GenTextFile(parser, path, filename);
480
0
    if (err) {
481
0
      status_detail = " (" + std::string(err) + ")";
482
0
      return Status::ERROR;
483
0
    }
484
0
    return Status::OK;
485
0
  }
486
487
  // Generate code from the provided `buffer` of given `length`. The buffer is a
488
  // serialized reflection.fbs.
489
0
  Status GenerateCode(const uint8_t*, int64_t, const CodeGenOptions&) override {
490
0
    return Status::NOT_IMPLEMENTED;
491
0
  }
492
493
  Status GenerateMakeRule(const Parser& parser, const std::string& path,
494
                          const std::string& filename,
495
0
                          std::string& output) override {
496
0
    output = TextMakeRule(parser, path, filename);
497
0
    return Status::OK;
498
0
  }
499
500
  Status GenerateGrpcCode(const Parser& parser, const std::string& path,
501
0
                          const std::string& filename) override {
502
0
    (void)parser;
503
0
    (void)path;
504
0
    (void)filename;
505
0
    return Status::NOT_IMPLEMENTED;
506
0
  }
507
508
  Status GenerateRootFile(const Parser& parser,
509
0
                          const std::string& path) override {
510
0
    (void)parser;
511
0
    (void)path;
512
0
    return Status::NOT_IMPLEMENTED;
513
0
  }
514
515
0
  bool IsSchemaOnly() const override { return false; }
516
517
0
  bool SupportsBfbsGeneration() const override { return false; }
518
519
0
  bool SupportsRootFileGeneration() const override { return false; }
520
521
0
  IDLOptions::Language Language() const override { return IDLOptions::kJson; }
522
523
0
  std::string LanguageName() const override { return "text"; }
524
};
525
526
}  // namespace
527
528
0
std::unique_ptr<CodeGenerator> NewTextCodeGenerator() {
529
0
  return std::unique_ptr<TextCodeGenerator>(new TextCodeGenerator());
530
0
}
531
532
}  // namespace flatbuffers