File: context.h

package info (click to toggle)
chromium 139.0.7258.127-1
  • links: PTS, VCS
  • area: main
  • in suites:
  • size: 6,122,068 kB
  • sloc: cpp: 35,100,771; ansic: 7,163,530; javascript: 4,103,002; python: 1,436,920; asm: 946,517; xml: 746,709; pascal: 187,653; perl: 88,691; sh: 88,436; objc: 79,953; sql: 51,488; cs: 44,583; fortran: 24,137; makefile: 22,147; tcl: 15,277; php: 13,980; yacc: 8,984; ruby: 7,485; awk: 3,720; lisp: 3,096; lex: 1,327; ada: 727; jsp: 228; sed: 36
file content (149 lines) | stat: -rw-r--r-- 4,441 bytes parent folder | download | duplicates (5)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
// Protocol Buffers - Google's data interchange format
// Copyright 2024 Google LLC.  All rights reserved.
//
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file or at
// https://developers.google.com/open-source/licenses/bsd

#ifndef GOOGLE_PROTOBUF_COMPILER_HPB_CONTEXT_H__
#define GOOGLE_PROTOBUF_COMPILER_HPB_CONTEXT_H__

#include <string>

#include "absl/strings/ascii.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/str_replace.h"
#include "absl/strings/string_view.h"
#include "absl/strings/substitute.h"
#include "absl/types/source_location.h"
#include "absl/types/span.h"
#include "google/protobuf/descriptor.h"
#include "google/protobuf/io/printer.h"
#include "google/protobuf/io/zero_copy_stream.h"
#include "upb/reflection/def.hpp"
#include "upb_generator/common/cpp_to_upb_def.h"

namespace google::protobuf::hpb_generator {

enum class Backend { UPB, CPP };

struct Options {
  Backend backend = Backend::UPB;
};

/**
 * This Context object will be used throughout hpb generation.
 * It is a thin wrapper around an io::Printer and can be easily extended
 * to support more options.
 *
 * Expected usage is:
 * SomeGenerationFunc(..., Context& context) {
 *   context.Emit({{"some_key", some_computed_val}}, R"cc(
 *   // hpb gencode ...
 *  )cc);
 * }
 */
class Context final {
 public:
  Context(const FileDescriptor* file, io::ZeroCopyOutputStream* stream,
          const Options& options)
      : stream_(stream), printer_(stream_), options_(options) {
    BuildDefPool(file);
  }

  void Emit(absl::Span<const io::Printer::Sub> vars, absl::string_view format,
            absl::SourceLocation loc = absl::SourceLocation::current()) {
    printer_.Emit(vars, format, loc);
  }

  void Emit(absl::string_view format,
            absl::SourceLocation loc = absl::SourceLocation::current()) {
    printer_.Emit(format, loc);
  }

  // TODO: b/373438292 - Remove EmitLegacy in favor of Emit.
  // This is an interim solution while we migrate from Output to io::Printer
  template <class... Arg>
  void EmitLegacy(absl::string_view format, const Arg&... arg) {
    auto res = absl::Substitute(format, arg...);
    printer_.Emit(res, absl::SourceLocation::current());
  }

  const Options& options() { return options_; }
  io::Printer& printer() { return printer_; }

  inline std::string GetLayoutIndex(const FieldDescriptor* field) {
    return absl::StrCat(
        upb::generator::FindBaseFieldDef(pool_, field).layout_index());
  }

  Context(const Context&) = delete;
  Context& operator=(const Context&) = delete;
  Context(Context&&) = delete;
  Context& operator=(Context&&) = delete;

 private:
  inline void BuildDefPool(const FileDescriptor* file) {
    upb::generator::AddFile(file, &pool_);
  }

  io::ZeroCopyOutputStream* stream_;
  io::Printer printer_;
  const Options& options_;
  upb::DefPool pool_;
};

// TODO: b/373438292 - re-house these 4 legacy funcs post io::Printer move
inline std::string ToCIdent(absl::string_view str) {
  return absl::StrReplaceAll(str, {{".", "_"}, {"/", "_"}, {"-", "_"}});
}

inline std::string ToPreproc(absl::string_view str) {
  return absl::AsciiStrToUpper(ToCIdent(str));
}

inline void EmitFileWarning(const google::protobuf::FileDescriptor* file, Context& ctx) {
  ctx.EmitLegacy(
      R"cc(
        /* This file was generated by hpb_generator (Handle Protobuf) "
        from the input
         * file:
         *
         *     $0
         *
         * Do not edit -- your changes will be discarded when the file is
         * regenerated. */
      )cc",
      file->name());
  ctx.Emit("\n");
}

// TODO: b/346865271 append ::hpb instead of ::protos after namespace swap
inline std::string NamespaceFromPackageName(absl::string_view package_name) {
  return absl::StrCat(absl::StrReplaceAll(package_name, {{".", "::"}}),
                      "::protos");
}

template <typename T>
void WrapNamespace(const google::protobuf::FileDescriptor* file, Context& ctx, T&& body) {
  if (file->package().empty()) {
    body();
  } else {
    ctx.Emit(
        {
            {"body", body},
            {"namespace", NamespaceFromPackageName(file->package())},
        },
        R"cc(
          namespace $namespace$ {

          $body$

          }  // namespace $namespace$
        )cc");
  }
}
}  // namespace protobuf
}  // namespace google::hpb_generator

#endif  // GOOGLE_PROTOBUF_COMPILER_HPB_CONTEXT_H__