summaryrefslogtreecommitdiff
path: root/upb/descriptor/reader.h
blob: f9d00469e6446661bafb7059ed45ceca2b5db96c (plain)
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
150
151
152
/*
 * upb - a minimalist implementation of protocol buffers.
 *
 * Copyright (c) 2011 Google Inc.  See LICENSE for details.
 * Author: Josh Haberman <jhaberman@gmail.com>
 *
 * upb::descriptor::Reader provides a way of building upb::Defs from
 * data in descriptor.proto format.
 */

#ifndef UPB_DESCRIPTOR_H
#define UPB_DESCRIPTOR_H

#include "upb/sink.h"

#ifdef __cplusplus
namespace upb {
namespace descriptor {
class Reader;
}  // namespace descriptor
}  // namespace upb

typedef upb::descriptor::Reader upb_descreader;
#else
struct upb_descreader;
typedef struct upb_descreader upb_descreader;
#endif

// Internal-only structs used by Reader.

// upb_deflist is an internal-only dynamic array for storing a growing list of
// upb_defs.
typedef struct {
 UPB_PRIVATE_FOR_CPP
  upb_def **defs;
  size_t len;
  size_t size;
  bool owned;
} upb_deflist;

// We keep a stack of all the messages scopes we are currently in, as well as
// the top-level file scope.  This is necessary to correctly qualify the
// definitions that are contained inside.  "name" tracks the name of the
// message or package (a bare name -- not qualified by any enclosing scopes).
typedef struct {
 UPB_PRIVATE_FOR_CPP
  char *name;
  // Index of the first def that is under this scope.  For msgdefs, the
  // msgdef itself is at start-1.
  int start;
} upb_descreader_frame;

// The maximum number of nested declarations that are allowed, ie.
// message Foo {
//   message Bar {
//     message Baz {
//     }
//   }
// }
//
// This is a resource limit that affects how big our runtime stack can grow.
// TODO: make this a runtime-settable property of the Reader instance.
#define UPB_MAX_MESSAGE_NESTING 64

#ifdef __cplusplus

// Class that receives descriptor data according to the descriptor.proto schema
// and use it to build upb::Defs corresponding to that schema.
class upb::descriptor::Reader {
 public:
  // These handlers must have come from NewHandlers() and must outlive the
  // Reader.
  //
  // TODO: generate the handlers statically (like we do with the
  // descriptor.proto defs) so that there is no need to pass this parameter (or
  // to build/memory-manage the handlers at runtime at all).  Unfortunately this
  // is a bit tricky to implement for Handlers, but necessary to simplify this
  // interface.
  Reader(const Handlers* handlers, Status* status);
  ~Reader();

  // Resets the reader's state and discards any defs it may have built.
  void Reset();

  // The reader's input; this is where descriptor.proto data should be sent.
  Sink* input();

  // Returns an array of all defs that have been parsed, and transfers ownership
  // of them to "owner".  The number of defs is stored in *n.  Ownership of the
  // returned array is retained and is invalidated by any other call into
  // Reader.
  //
  // These defs are not frozen or resolved; they are ready to be added to a
  // symtab.
  upb::Def** GetDefs(void* owner, int* n);

  // Builds and returns handlers for the reader, owned by "owner."
  static Handlers* NewHandlers(const void* owner);

 private:
#else
struct upb_descreader {
#endif
  char sink[sizeof(upb_sink)];
  upb_deflist defs;
  upb_descreader_frame stack[UPB_MAX_MESSAGE_NESTING];
  int stack_len;

  uint32_t number;
  char *name;
  bool saw_number;
  bool saw_name;

  char *default_string;

  upb_fielddef *f;
};

#ifdef __cplusplus
extern "C" {
#endif

// C API.
void upb_descreader_init(upb_descreader *r, const upb_handlers *handlers,
                         upb_status *status);
void upb_descreader_uninit(upb_descreader *r);
void upb_descreader_reset(upb_descreader *r);
upb_sink *upb_descreader_input(upb_descreader *r);
upb_def **upb_descreader_getdefs(upb_descreader *r, void *owner, int *n);
const upb_handlers *upb_descreader_newhandlers(const void *owner);

#ifdef __cplusplus
}  // extern "C"

// C++ implementation details. /////////////////////////////////////////////////

namespace upb {
namespace descriptor {
inline Reader::Reader(const Handlers *h, Status *s) {
  upb_descreader_init(this, h, s);
}
inline Reader::~Reader() { upb_descreader_uninit(this); }
inline void Reader::Reset() { upb_descreader_reset(this); }
inline Sink* Reader::input() { return upb_descreader_input(this); }
inline upb::Def** Reader::GetDefs(void* owner, int* n) {
  return upb_descreader_getdefs(this, owner, n);
}
}  // namespace descriptor
}  // namespace upb
#endif

#endif  // UPB_DESCRIPTOR_H
generated by cgit on debian on lair
contact matthew@masot.net with questions or feedback