• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *
3  * Tests for C++ wrappers.
4  */
5 
6 #include <stdio.h>
7 #include <string.h>
8 
9 #include <fstream>
10 #include <iostream>
11 #include <set>
12 #include <sstream>
13 
14 #include "tests/test_cpp.upbdefs.h"
15 #include "tests/upb_test.h"
16 #include "upb/def.h"
17 #include "upb/handlers.h"
18 #include "upb/pb/decoder.h"
19 #include "upb/pb/textprinter.h"
20 #include "upb/port_def.inc"
21 #include "upb/upb.h"
22 
23 template <class T>
AssertInsert(T * const container,const typename T::value_type & val)24 void AssertInsert(T* const container, const typename T::value_type& val) {
25   bool inserted = container->insert(val).second;
26   ASSERT(inserted);
27 }
28 
29 //
30 // Tests for registering and calling handlers in all their variants.
31 // This test code is very repetitive because we have to declare each
32 // handler function variant separately, and they all have different
33 // signatures so it does not lend itself well to templates.
34 //
35 // We test three handler types:
36 //   StartMessage (no data params)
37 //   Int32        (1 data param (int32_t))
38 //   String Buf   (2 data params (const char*, size_t))
39 //
40 // For each handler type we test all 8 handler variants:
41 //   (handler data?) x  (function/method) x (returns {void, success})
42 //
43 // The one notable thing we don't test at the moment is
44 // StartSequence/StartString handlers: these are different from StartMessage()
45 // in that they return void* for the sub-closure.  But this is exercised in
46 // other tests.
47 //
48 
49 static const int kExpectedHandlerData = 1232323;
50 
51 class StringBufTesterBase {
52  public:
53   static constexpr int kFieldNumber = 3;
54 
StringBufTesterBase()55   StringBufTesterBase() : seen_(false), handler_data_val_(0) {}
56 
CallAndVerify(upb::Sink sink,upb::FieldDefPtr f)57   void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
58     upb_selector_t start;
59     ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_STARTSTR, &start));
60     upb_selector_t str;
61     ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_STRING, &str));
62 
63     ASSERT(!seen_);
64     upb::Sink sub;
65     sink.StartMessage();
66     sink.StartString(start, 0, &sub);
67     size_t ret = sub.PutStringBuffer(str, &buf_, 5, &handle_);
68     ASSERT(seen_);
69     ASSERT(len_ == 5);
70     ASSERT(ret == 5);
71     ASSERT(handler_data_val_ == kExpectedHandlerData);
72   }
73 
74  protected:
75   bool seen_;
76   int handler_data_val_;
77   size_t len_;
78   char buf_;
79   upb_bufhandle handle_;
80 };
81 
82 // Test 8 combinations of:
83 //   (handler data?) x (buffer handle?) x (function/method)
84 //
85 // Then we add one test each for this variation: to prevent combinatorial
86 // explosion of these tests we don't test the full 16 combinations, but
87 // rely on our knowledge that the implementation processes the return wrapping
88 // in a second separate and independent stage:
89 //
90 //   (function/method)
91 
92 class StringBufTesterVoidMethodNoHandlerDataNoHandle
93     : public StringBufTesterBase {
94  public:
95   typedef StringBufTesterVoidMethodNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)96   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
97     UPB_UNUSED(f);
98     ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
99     handler_data_val_ = kExpectedHandlerData;
100   }
101 
102  private:
Handler(const char * buf,size_t len)103   void Handler(const char *buf, size_t len) {
104     ASSERT(buf == &buf_);
105     seen_ = true;
106     len_ = len;
107   }
108 };
109 
110 class StringBufTesterVoidMethodNoHandlerDataWithHandle
111     : public StringBufTesterBase {
112  public:
113   typedef StringBufTesterVoidMethodNoHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)114   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
115     UPB_UNUSED(f);
116     ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
117     handler_data_val_ = kExpectedHandlerData;
118   }
119 
120  private:
Handler(const char * buf,size_t len,const upb_bufhandle * handle)121   void Handler(const char *buf, size_t len, const upb_bufhandle* handle) {
122     ASSERT(buf == &buf_);
123     ASSERT(handle == &handle_);
124     seen_ = true;
125     len_ = len;
126   }
127 };
128 
129 class StringBufTesterVoidMethodWithHandlerDataNoHandle
130     : public StringBufTesterBase {
131  public:
132   typedef StringBufTesterVoidMethodWithHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)133   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
134     UPB_UNUSED(f);
135     ASSERT(h.SetStringHandler(
136         f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
137   }
138 
139  private:
Handler(const int * hd,const char * buf,size_t len)140   void Handler(const int* hd, const char *buf, size_t len) {
141     ASSERT(buf == &buf_);
142     handler_data_val_ = *hd;
143     seen_ = true;
144     len_ = len;
145   }
146 };
147 
148 class StringBufTesterVoidMethodWithHandlerDataWithHandle
149     : public StringBufTesterBase {
150  public:
151   typedef StringBufTesterVoidMethodWithHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)152   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
153     UPB_UNUSED(f);
154     ASSERT(h.SetStringHandler(
155         f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
156   }
157 
158  private:
Handler(const int * hd,const char * buf,size_t len,const upb_bufhandle * handle)159   void Handler(const int* hd, const char* buf, size_t len,
160                const upb_bufhandle* handle) {
161     ASSERT(buf == &buf_);
162     ASSERT(handle == &handle_);
163     handler_data_val_ = *hd;
164     seen_ = true;
165     len_ = len;
166   }
167 };
168 
169 class StringBufTesterVoidFunctionNoHandlerDataNoHandle
170     : public StringBufTesterBase {
171  public:
172   typedef StringBufTesterVoidFunctionNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)173   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
174     UPB_UNUSED(f);
175     ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
176     handler_data_val_ = kExpectedHandlerData;
177   }
178 
179  private:
Handler(ME * t,const char * buf,size_t len)180   static void Handler(ME* t, const char *buf, size_t len) {
181     ASSERT(buf == &t->buf_);
182     t->seen_ = true;
183     t->len_ = len;
184   }
185 };
186 
187 class StringBufTesterVoidFunctionNoHandlerDataWithHandle
188     : public StringBufTesterBase {
189  public:
190   typedef StringBufTesterVoidFunctionNoHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)191   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
192     UPB_UNUSED(f);
193     ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
194     handler_data_val_ = kExpectedHandlerData;
195   }
196 
197  private:
Handler(ME * t,const char * buf,size_t len,const upb_bufhandle * handle)198   static void Handler(ME* t, const char* buf, size_t len,
199                       const upb_bufhandle* handle) {
200     ASSERT(buf == &t->buf_);
201     ASSERT(handle == &t->handle_);
202     t->seen_ = true;
203     t->len_ = len;
204   }
205 };
206 
207 class StringBufTesterVoidFunctionWithHandlerDataNoHandle
208     : public StringBufTesterBase {
209  public:
210   typedef StringBufTesterVoidFunctionWithHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)211   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
212     UPB_UNUSED(f);
213     ASSERT(h.SetStringHandler(
214         f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
215   }
216 
217  private:
Handler(ME * t,const int * hd,const char * buf,size_t len)218   static void Handler(ME* t, const int* hd, const char *buf, size_t len) {
219     ASSERT(buf == &t->buf_);
220     t->handler_data_val_ = *hd;
221     t->seen_ = true;
222     t->len_ = len;
223   }
224 };
225 
226 class StringBufTesterVoidFunctionWithHandlerDataWithHandle
227     : public StringBufTesterBase {
228  public:
229   typedef StringBufTesterVoidFunctionWithHandlerDataWithHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)230   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
231     UPB_UNUSED(f);
232     ASSERT(h.SetStringHandler(
233         f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
234   }
235 
236  private:
Handler(ME * t,const int * hd,const char * buf,size_t len,const upb_bufhandle * handle)237   static void Handler(ME* t, const int* hd, const char* buf, size_t len,
238                       const upb_bufhandle* handle) {
239     ASSERT(buf == &t->buf_);
240     ASSERT(handle == &t->handle_);
241     t->handler_data_val_ = *hd;
242     t->seen_ = true;
243     t->len_ = len;
244   }
245 };
246 
247 class StringBufTesterSizeTMethodNoHandlerDataNoHandle
248     : public StringBufTesterBase {
249  public:
250   typedef StringBufTesterSizeTMethodNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)251   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
252     UPB_UNUSED(f);
253     ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
254     handler_data_val_ = kExpectedHandlerData;
255   }
256 
257  private:
Handler(const char * buf,size_t len)258   size_t Handler(const char *buf, size_t len) {
259     ASSERT(buf == &buf_);
260     seen_ = true;
261     len_ = len;
262     return len;
263   }
264 };
265 
266 class StringBufTesterBoolMethodNoHandlerDataNoHandle
267     : public StringBufTesterBase {
268  public:
269   typedef StringBufTesterBoolMethodNoHandlerDataNoHandle ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)270   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
271     UPB_UNUSED(f);
272     ASSERT(h.SetStringHandler(f, UpbMakeHandler(&ME::Handler)));
273     handler_data_val_ = kExpectedHandlerData;
274   }
275 
276  private:
Handler(const char * buf,size_t len)277   bool Handler(const char *buf, size_t len) {
278     ASSERT(buf == &buf_);
279     seen_ = true;
280     len_ = len;
281     return true;
282   }
283 };
284 
285 class StartMsgTesterBase {
286  public:
287   // We don't need the FieldDef it will create, but the test harness still
288   // requires that we provide one.
289   static constexpr int kFieldNumber = 3;
290 
StartMsgTesterBase()291   StartMsgTesterBase() : seen_(false), handler_data_val_(0) {}
292 
CallAndVerify(upb::Sink sink,upb::FieldDefPtr f)293   void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
294     UPB_UNUSED(f);
295     ASSERT(!seen_);
296     sink.StartMessage();
297     ASSERT(seen_);
298     ASSERT(handler_data_val_ == kExpectedHandlerData);
299   }
300 
301  protected:
302   bool seen_;
303   int handler_data_val_;
304 };
305 
306 // Test all 8 combinations of:
307 //   (handler data?) x  (function/method) x (returns {void, bool})
308 
309 class StartMsgTesterVoidFunctionNoHandlerData : public StartMsgTesterBase {
310  public:
311   typedef StartMsgTesterVoidFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)312   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
313     UPB_UNUSED(f);
314     ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&Handler)));
315     handler_data_val_ = kExpectedHandlerData;
316   }
317 
318  private:
319   //static void Handler(ME* t) {
Handler(ME * t)320   static void Handler(ME* t) {
321     t->seen_ = true;
322   }
323 };
324 
325 class StartMsgTesterBoolFunctionNoHandlerData : public StartMsgTesterBase {
326  public:
327   typedef StartMsgTesterBoolFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)328   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
329     UPB_UNUSED(f);
330     ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&Handler)));
331     handler_data_val_ = kExpectedHandlerData;
332   }
333 
334  private:
Handler(ME * t)335   static bool Handler(ME* t) {
336     t->seen_ = true;
337     return true;
338   }
339 };
340 
341 class StartMsgTesterVoidMethodNoHandlerData : public StartMsgTesterBase {
342  public:
343   typedef StartMsgTesterVoidMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)344   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
345     UPB_UNUSED(f);
346     ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&ME::Handler)));
347     handler_data_val_ = kExpectedHandlerData;
348   }
349 
350  private:
Handler()351   void Handler() {
352     seen_ = true;
353   }
354 };
355 
356 class StartMsgTesterBoolMethodNoHandlerData : public StartMsgTesterBase {
357  public:
358   typedef StartMsgTesterBoolMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)359   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
360     UPB_UNUSED(f);
361     ASSERT(h.SetStartMessageHandler(UpbMakeHandler(&ME::Handler)));
362     handler_data_val_ = kExpectedHandlerData;
363   }
364 
365  private:
Handler()366   bool Handler() {
367     seen_ = true;
368     return true;
369   }
370 };
371 
372 class StartMsgTesterVoidFunctionWithHandlerData : public StartMsgTesterBase {
373  public:
374   typedef StartMsgTesterVoidFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)375   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
376     UPB_UNUSED(f);
377     ASSERT(h.SetStartMessageHandler(
378         UpbBind(&Handler, new int(kExpectedHandlerData))));
379   }
380 
381  private:
Handler(ME * t,const int * hd)382   static void Handler(ME* t, const int* hd) {
383     t->handler_data_val_ = *hd;
384     t->seen_ = true;
385   }
386 };
387 
388 class StartMsgTesterBoolFunctionWithHandlerData : public StartMsgTesterBase {
389  public:
390   typedef StartMsgTesterBoolFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)391   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
392     UPB_UNUSED(f);
393     ASSERT(h.SetStartMessageHandler(
394         UpbBind(&Handler, new int(kExpectedHandlerData))));
395   }
396 
397  private:
Handler(ME * t,const int * hd)398   static bool Handler(ME* t, const int* hd) {
399     t->handler_data_val_ = *hd;
400     t->seen_ = true;
401     return true;
402   }
403 };
404 
405 class StartMsgTesterVoidMethodWithHandlerData : public StartMsgTesterBase {
406  public:
407   typedef StartMsgTesterVoidMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)408   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
409     UPB_UNUSED(f);
410     ASSERT(h.SetStartMessageHandler(
411         UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
412   }
413 
414  private:
Handler(const int * hd)415   void Handler(const int* hd) {
416     handler_data_val_ = *hd;
417     seen_ = true;
418   }
419 };
420 
421 class StartMsgTesterBoolMethodWithHandlerData : public StartMsgTesterBase {
422  public:
423   typedef StartMsgTesterBoolMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)424   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
425     UPB_UNUSED(f);
426     ASSERT(h.SetStartMessageHandler(
427         UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
428   }
429 
430  private:
Handler(const int * hd)431   bool Handler(const int* hd) {
432     handler_data_val_ = *hd;
433     seen_ = true;
434     return true;
435   }
436 };
437 
438 class Int32ValueTesterBase {
439  public:
440   static constexpr int kFieldNumber = 1;
441 
Int32ValueTesterBase()442   Int32ValueTesterBase() : seen_(false), val_(0), handler_data_val_(0) {}
443 
CallAndVerify(upb::Sink sink,upb::FieldDefPtr f)444   void CallAndVerify(upb::Sink sink, upb::FieldDefPtr f) {
445     upb_selector_t s;
446     ASSERT(upb_handlers_getselector(f.ptr(), UPB_HANDLER_INT32, &s));
447 
448     ASSERT(!seen_);
449     sink.PutInt32(s, 5);
450     ASSERT(seen_);
451     ASSERT(handler_data_val_ == kExpectedHandlerData);
452     ASSERT(val_ == 5);
453   }
454 
455  protected:
456   bool seen_;
457   int32_t val_;
458   int handler_data_val_;
459 };
460 
461 // Test all 8 combinations of:
462 //   (handler data?) x  (function/method) x (returns {void, bool})
463 
464 class ValueTesterInt32VoidFunctionNoHandlerData
465     : public Int32ValueTesterBase {
466  public:
467   typedef ValueTesterInt32VoidFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)468   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
469     ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&Handler)));
470     handler_data_val_ = kExpectedHandlerData;
471   }
472 
473  private:
Handler(ME * t,int32_t val)474   static void Handler(ME* t, int32_t val) {
475     t->val_ = val;
476     t->seen_ = true;
477   }
478 };
479 
480 class ValueTesterInt32BoolFunctionNoHandlerData
481     : public Int32ValueTesterBase {
482  public:
483   typedef ValueTesterInt32BoolFunctionNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)484   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
485     ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&Handler)));
486     handler_data_val_ = kExpectedHandlerData;
487   }
488 
489  private:
Handler(ME * t,int32_t val)490   static bool Handler(ME* t, int32_t val) {
491     t->val_ = val;
492     t->seen_ = true;
493     return true;
494   }
495 };
496 
497 class ValueTesterInt32VoidMethodNoHandlerData : public Int32ValueTesterBase {
498  public:
499   typedef ValueTesterInt32VoidMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)500   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
501     ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&ME::Handler)));
502     handler_data_val_ = kExpectedHandlerData;
503   }
504 
505  private:
Handler(int32_t val)506   void Handler(int32_t val) {
507     val_ = val;
508     seen_ = true;
509   }
510 };
511 
512 class ValueTesterInt32BoolMethodNoHandlerData : public Int32ValueTesterBase {
513  public:
514   typedef ValueTesterInt32BoolMethodNoHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)515   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
516     ASSERT(h.SetInt32Handler(f, UpbMakeHandler(&ME::Handler)));
517     handler_data_val_ = kExpectedHandlerData;
518   }
519 
520  private:
Handler(int32_t val)521   bool Handler(int32_t val) {
522     val_ = val;
523     seen_ = true;
524     return true;
525   }
526 };
527 
528 class ValueTesterInt32VoidFunctionWithHandlerData
529     : public Int32ValueTesterBase {
530  public:
531   typedef ValueTesterInt32VoidFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)532   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
533     ASSERT(h.SetInt32Handler(
534         f, UpbBind(&Handler, new int(kExpectedHandlerData))));
535   }
536 
537  private:
Handler(ME * t,const int * hd,int32_t val)538   static void Handler(ME* t, const int* hd, int32_t val) {
539     t->val_ = val;
540     t->handler_data_val_ = *hd;
541     t->seen_ = true;
542   }
543 };
544 
545 class ValueTesterInt32BoolFunctionWithHandlerData
546     : public Int32ValueTesterBase {
547  public:
548   typedef ValueTesterInt32BoolFunctionWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)549   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
550     ASSERT(h.SetInt32Handler(
551         f, UpbBind(&Handler, new int(kExpectedHandlerData))));
552   }
553 
554  private:
Handler(ME * t,const int * hd,int32_t val)555   static bool Handler(ME* t, const int* hd, int32_t val) {
556     t->val_ = val;
557     t->handler_data_val_ = *hd;
558     t->seen_ = true;
559     return true;
560   }
561 };
562 
563 class ValueTesterInt32VoidMethodWithHandlerData : public Int32ValueTesterBase {
564  public:
565   typedef ValueTesterInt32VoidMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)566   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
567     ASSERT(h.SetInt32Handler(
568         f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
569   }
570 
571  private:
Handler(const int * hd,int32_t val)572   void Handler(const int* hd, int32_t val) {
573     val_ = val;
574     handler_data_val_ = *hd;
575     seen_ = true;
576   }
577 };
578 
579 class ValueTesterInt32BoolMethodWithHandlerData : public Int32ValueTesterBase {
580  public:
581   typedef ValueTesterInt32BoolMethodWithHandlerData ME;
Register(upb::HandlersPtr h,upb::FieldDefPtr f)582   void Register(upb::HandlersPtr h, upb::FieldDefPtr f) {
583     ASSERT(h.SetInt32Handler(
584         f, UpbBind(&ME::Handler, new int(kExpectedHandlerData))));
585   }
586 
587  private:
Handler(const int * hd,int32_t val)588   bool Handler(const int* hd, int32_t val) {
589     val_ = val;
590     handler_data_val_ = *hd;
591     seen_ = true;
592     return true;
593   }
594 };
595 
596 template <class T>
RegisterHandlers(const void * closure,upb::Handlers * h_ptr)597 void RegisterHandlers(const void* closure, upb::Handlers* h_ptr) {
598   T* tester = const_cast<T*>(static_cast<const T*>(closure));
599   upb::HandlersPtr h(h_ptr);
600   upb::FieldDefPtr f = h.message_def().FindFieldByNumber(T::kFieldNumber);
601   ASSERT(f);
602   tester->Register(h, f);
603 }
604 
605 template <class T>
TestHandler()606 void TestHandler() {
607   T tester;
608   upb::SymbolTable symtab;
609   upb::HandlerCache cache(&RegisterHandlers<T>, &tester);
610   upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
611   ASSERT(md);
612   upb::FieldDefPtr f = md.FindFieldByNumber(T::kFieldNumber);
613   ASSERT(f);
614 
615   const upb::Handlers* h = cache.Get(md);
616 
617   upb::Sink sink(h, &tester);
618   tester.CallAndVerify(sink, f);
619 }
620 
621 class T1 {};
622 class T2 {};
623 
624 template <class C>
DoNothingHandler(C * closure)625 void DoNothingHandler(C* closure) {
626   UPB_UNUSED(closure);
627 }
628 
629 template <class C>
DoNothingInt32Handler(C * closure,int32_t val)630 void DoNothingInt32Handler(C* closure, int32_t val) {
631   UPB_UNUSED(closure);
632   UPB_UNUSED(val);
633 }
634 
635 template <class R>
636 class DoNothingStartHandler {
637  public:
638   // We wrap these functions inside of a class for a somewhat annoying reason.
639   // UpbMakeHandler() is a macro, so we can't say
640   //    UpbMakeHandler(DoNothingStartHandler<T1, T2>)
641   //
642   // because otherwise the preprocessor gets confused at the comma and tries to
643   // make it two macro arguments.  The usual solution doesn't work either:
644   //    UpbMakeHandler((DoNothingStartHandler<T1, T2>))
645   //
646   // If we do that the macro expands correctly, but then it tries to pass that
647   // parenthesized expression as a template parameter, ie. Type<(F)>, which
648   // isn't legal C++ (Clang will compile it but complains with
649   //    warning: address non-type template argument cannot be surrounded by
650   //    parentheses
651   //
652   // This two-level thing allows us to effectively pass two template parameters,
653   // but without any commas:
654   //    UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)
655   template <class C>
Handler(C * closure)656   static R* Handler(C* closure) {
657     UPB_UNUSED(closure);
658     return NULL;
659   }
660 
661   template <class C>
String(C * closure,size_t size_len)662   static R* String(C* closure, size_t size_len) {
663     UPB_UNUSED(closure);
664     UPB_UNUSED(size_len);
665     return NULL;
666   }
667 };
668 
669 template <class C>
DoNothingStringBufHandler(C * closure,const char * buf,size_t len)670 void DoNothingStringBufHandler(C* closure, const char *buf, size_t len) {
671   UPB_UNUSED(closure);
672   UPB_UNUSED(buf);
673   UPB_UNUSED(len);
674 }
675 
676 template <class C>
DoNothingEndMessageHandler(C * closure,upb_status * status)677 void DoNothingEndMessageHandler(C* closure, upb_status *status) {
678   UPB_UNUSED(closure);
679   UPB_UNUSED(status);
680 }
681 
RegisterMismatchedTypes(const void * closure,upb::Handlers * h_ptr)682 void RegisterMismatchedTypes(const void* closure, upb::Handlers* h_ptr) {
683   upb::HandlersPtr h(h_ptr);
684   UPB_UNUSED(closure);
685 
686   upb::MessageDefPtr md(h.message_def());
687   ASSERT(md);
688   upb::FieldDefPtr i32 = md.FindFieldByName("i32");
689   upb::FieldDefPtr r_i32 = md.FindFieldByName("r_i32");
690   upb::FieldDefPtr str = md.FindFieldByName("str");
691   upb::FieldDefPtr r_str = md.FindFieldByName("r_str");
692   upb::FieldDefPtr msg = md.FindFieldByName("msg");
693   upb::FieldDefPtr r_msg = md.FindFieldByName("r_msg");
694   ASSERT(i32);
695   ASSERT(r_i32);
696   ASSERT(str);
697   ASSERT(r_str);
698   ASSERT(msg);
699   ASSERT(r_msg);
700 
701   // Establish T1 as the top-level closure type.
702   ASSERT(h.SetInt32Handler(i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
703 
704   // Now any other attempt to set another handler with T2 as the top-level
705   // closure should fail.  But setting these same handlers with T1 as the
706   // top-level closure will succeed.
707   ASSERT(!h.SetStartMessageHandler(UpbMakeHandler(DoNothingHandler<T2>)));
708   ASSERT(h.SetStartMessageHandler(UpbMakeHandler(DoNothingHandler<T1>)));
709 
710   ASSERT(
711       !h.SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler<T2>)));
712   ASSERT(
713       h.SetEndMessageHandler(UpbMakeHandler(DoNothingEndMessageHandler<T1>)));
714 
715   ASSERT(!h.SetStartStringHandler(
716               str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T2>)));
717   ASSERT(h.SetStartStringHandler(
718               str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T1>)));
719 
720   ASSERT(!h.SetEndStringHandler(str, UpbMakeHandler(DoNothingHandler<T2>)));
721   ASSERT(h.SetEndStringHandler(str, UpbMakeHandler(DoNothingHandler<T1>)));
722 
723   ASSERT(!h.SetStartSubMessageHandler(
724               msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
725   ASSERT(h.SetStartSubMessageHandler(
726               msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
727 
728   ASSERT(
729       !h.SetEndSubMessageHandler(msg, UpbMakeHandler(DoNothingHandler<T2>)));
730   ASSERT(
731       h.SetEndSubMessageHandler(msg, UpbMakeHandler(DoNothingHandler<T1>)));
732 
733   ASSERT(!h.SetStartSequenceHandler(
734               r_i32, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
735   ASSERT(h.SetStartSequenceHandler(
736               r_i32, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
737 
738   ASSERT(!h.SetEndSequenceHandler(
739               r_i32, UpbMakeHandler(DoNothingHandler<T2>)));
740   ASSERT(h.SetEndSequenceHandler(
741               r_i32, UpbMakeHandler(DoNothingHandler<T1>)));
742 
743   ASSERT(!h.SetStartSequenceHandler(
744               r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
745   ASSERT(h.SetStartSequenceHandler(
746               r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
747 
748   ASSERT(!h.SetEndSequenceHandler(
749               r_msg, UpbMakeHandler(DoNothingHandler<T2>)));
750   ASSERT(h.SetEndSequenceHandler(
751               r_msg, UpbMakeHandler(DoNothingHandler<T1>)));
752 
753   ASSERT(!h.SetStartSequenceHandler(
754               r_str, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
755   ASSERT(h.SetStartSequenceHandler(
756               r_str, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
757 
758   ASSERT(!h.SetEndSequenceHandler(
759               r_str, UpbMakeHandler(DoNothingHandler<T2>)));
760   ASSERT(h.SetEndSequenceHandler(
761               r_str, UpbMakeHandler(DoNothingHandler<T1>)));
762 
763   // By setting T1 as the return type for the Start* handlers we have
764   // established T1 as the type of the sequence and string frames.
765   // Setting callbacks that use T2 should fail, but T1 should succeed.
766   ASSERT(
767       !h.SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler<T2>)));
768   ASSERT(
769       h.SetStringHandler(str, UpbMakeHandler(DoNothingStringBufHandler<T1>)));
770 
771   ASSERT(!h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T2>)));
772   ASSERT(h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
773 
774   ASSERT(!h.SetStartSubMessageHandler(
775               r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T2>)));
776   ASSERT(h.SetStartSubMessageHandler(
777               r_msg, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
778 
779   ASSERT(!h.SetEndSubMessageHandler(r_msg,
780                                      UpbMakeHandler(DoNothingHandler<T2>)));
781   ASSERT(h.SetEndSubMessageHandler(r_msg,
782                                     UpbMakeHandler(DoNothingHandler<T1>)));
783 
784   ASSERT(!h.SetStartStringHandler(
785               r_str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T2>)));
786   ASSERT(h.SetStartStringHandler(
787               r_str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T1>)));
788 
789   ASSERT(
790       !h.SetEndStringHandler(r_str, UpbMakeHandler(DoNothingHandler<T2>)));
791   ASSERT(h.SetEndStringHandler(r_str, UpbMakeHandler(DoNothingHandler<T1>)));
792 
793   ASSERT(!h.SetStringHandler(r_str,
794                               UpbMakeHandler(DoNothingStringBufHandler<T2>)));
795   ASSERT(h.SetStringHandler(r_str,
796                              UpbMakeHandler(DoNothingStringBufHandler<T1>)));
797 }
798 
RegisterMismatchedTypes2(const void * closure,upb::Handlers * h_ptr)799 void RegisterMismatchedTypes2(const void* closure, upb::Handlers* h_ptr) {
800   upb::HandlersPtr h(h_ptr);
801   UPB_UNUSED(closure);
802 
803   upb::MessageDefPtr md(h.message_def());
804   ASSERT(md);
805   upb::FieldDefPtr i32 = md.FindFieldByName("i32");
806   upb::FieldDefPtr r_i32 = md.FindFieldByName("r_i32");
807   upb::FieldDefPtr str = md.FindFieldByName("str");
808   upb::FieldDefPtr r_str = md.FindFieldByName("r_str");
809   upb::FieldDefPtr msg = md.FindFieldByName("msg");
810   upb::FieldDefPtr r_msg = md.FindFieldByName("r_msg");
811   ASSERT(i32);
812   ASSERT(r_i32);
813   ASSERT(str);
814   ASSERT(r_str);
815   ASSERT(msg);
816   ASSERT(r_msg);
817 
818   // For our second test we do the same in reverse.  We directly set the type of
819   // the frame and then observe failures at registering a Start* handler that
820   // returns a different type.
821 
822   // First establish the type of a sequence frame directly.
823   ASSERT(h.SetInt32Handler(r_i32, UpbMakeHandler(DoNothingInt32Handler<T1>)));
824 
825   // Now setting a StartSequence callback that returns a different type should
826   // fail.
827   ASSERT(!h.SetStartSequenceHandler(
828               r_i32, UpbMakeHandler(DoNothingStartHandler<T2>::Handler<T1>)));
829   ASSERT(h.SetStartSequenceHandler(
830               r_i32, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
831 
832   // Establish a string frame directly.
833   ASSERT(h.SetStringHandler(r_str,
834                              UpbMakeHandler(DoNothingStringBufHandler<T1>)));
835 
836   // Fail setting a StartString callback that returns a different type.
837   ASSERT(!h.SetStartStringHandler(
838               r_str, UpbMakeHandler(DoNothingStartHandler<T2>::String<T1>)));
839   ASSERT(h.SetStartStringHandler(
840       r_str, UpbMakeHandler(DoNothingStartHandler<T1>::String<T1>)));
841 
842   // The previous established T1 as the frame for the r_str sequence.
843   ASSERT(!h.SetStartSequenceHandler(
844               r_str, UpbMakeHandler(DoNothingStartHandler<T2>::Handler<T1>)));
845   ASSERT(h.SetStartSequenceHandler(
846       r_str, UpbMakeHandler(DoNothingStartHandler<T1>::Handler<T1>)));
847 }
848 
TestMismatchedTypes()849 void TestMismatchedTypes() {
850   // First create a schema for our test.
851   upb::SymbolTable symtab;
852   upb::HandlerCache handler_cache(&RegisterMismatchedTypes, nullptr);
853   upb::HandlerCache handler_cache2(&RegisterMismatchedTypes2, nullptr);
854   const upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
855 
856   // Now test the type-checking in handler registration.
857   handler_cache.Get(md);
858   handler_cache2.Get(md);
859 }
860 
861 class IntIncrementer {
862  public:
IntIncrementer(int * x)863   explicit IntIncrementer(int* x) : x_(x) { (*x_)++; }
~IntIncrementer()864   ~IntIncrementer() { (*x_)--; }
865 
Handler(void * closure,const IntIncrementer * incrementer,int32_t x)866   static void Handler(void* closure, const IntIncrementer* incrementer,
867                       int32_t x) {
868     UPB_UNUSED(closure);
869     UPB_UNUSED(incrementer);
870     UPB_UNUSED(x);
871   }
872 
873  private:
874   int* x_;
875 };
876 
RegisterIncrementor(const void * closure,upb::Handlers * h_ptr)877 void RegisterIncrementor(const void* closure, upb::Handlers* h_ptr) {
878   const int* x = static_cast<const int*>(closure);
879   upb::HandlersPtr h(h_ptr);
880   upb::FieldDefPtr f = h.message_def().FindFieldByName("i32");
881   h.SetInt32Handler(f, UpbBind(&IntIncrementer::Handler,
882                                new IntIncrementer(const_cast<int*>(x))));
883 }
884 
TestHandlerDataDestruction()885 void TestHandlerDataDestruction() {
886   int x = 0;
887 
888   {
889     upb::SymbolTable symtab;
890     upb::HandlerCache cache(&RegisterIncrementor, &x);
891     upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
892     cache.Get(md);
893     ASSERT(x == 1);
894   }
895 
896   ASSERT(x == 0);
897 }
898 
TestIteration()899 void TestIteration() {
900   upb::SymbolTable symtab;
901   upb::MessageDefPtr md(upb_test_TestMessage_getmsgdef(symtab.ptr()));
902 
903   // Test range-based for on both fields and oneofs (with the iterator adaptor).
904   int field_count = 0;
905   for (auto field : md.fields()) {
906     UPB_UNUSED(field);
907     field_count++;
908   }
909   ASSERT(field_count == md.field_count());
910 
911   int oneof_count = 0;
912   for (auto oneof : md.oneofs()) {
913     UPB_UNUSED(oneof);
914     oneof_count++;
915   }
916   ASSERT(oneof_count == md.oneof_count());
917 }
918 
TestArena()919 void TestArena() {
920   int n = 100000;
921 
922   struct Decrementer {
923     Decrementer(int* _p) : p(_p) {}
924     ~Decrementer() { (*p)--; }
925     int* p;
926   };
927 
928   {
929     upb::Arena arena;
930     for (int i = 0; i < n; i++) {
931       arena.Own(new Decrementer(&n));
932 
933       // Intersperse allocation and ensure we can write to it.
934       int* val = static_cast<int*>(upb_arena_malloc(arena.ptr(), sizeof(int)));
935       *val = i;
936     }
937 
938     // Test a large allocation.
939     upb_arena_malloc(arena.ptr(), 1000000);
940   }
941   ASSERT(n == 0);
942 
943   {
944     // Test fuse.
945     upb::Arena arena1;
946     upb::Arena arena2;
947 
948     arena1.Fuse(arena2);
949 
950     upb_arena_malloc(arena1.ptr(), 10000);
951     upb_arena_malloc(arena2.ptr(), 10000);
952   }
953 }
954 
TestInlinedArena()955 void TestInlinedArena() {
956   int n = 100000;
957 
958   struct Decrementer {
959     Decrementer(int* _p) : p(_p) {}
960     ~Decrementer() { (*p)--; }
961     int* p;
962   };
963 
964   {
965     upb::InlinedArena<1024> arena;
966     for (int i = 0; i < n; i++) {
967       arena.Own(new Decrementer(&n));
968 
969       // Intersperse allocation and ensure we can write to it.
970       int* val = static_cast<int*>(upb_arena_malloc(arena.ptr(), sizeof(int)));
971       *val = i;
972     }
973 
974     // Test a large allocation.
975     upb_arena_malloc(arena.ptr(), 1000000);
976   }
977   ASSERT(n == 0);
978 }
979 
980 extern "C" {
981 
run_tests()982 int run_tests() {
983   TestHandler<ValueTesterInt32VoidFunctionNoHandlerData>();
984   TestHandler<ValueTesterInt32BoolFunctionNoHandlerData>();
985   TestHandler<ValueTesterInt32VoidMethodNoHandlerData>();
986   TestHandler<ValueTesterInt32BoolMethodNoHandlerData>();
987   TestHandler<ValueTesterInt32VoidFunctionWithHandlerData>();
988   TestHandler<ValueTesterInt32BoolFunctionWithHandlerData>();
989   TestHandler<ValueTesterInt32VoidMethodWithHandlerData>();
990   TestHandler<ValueTesterInt32BoolMethodWithHandlerData>();
991 
992   TestHandler<StartMsgTesterVoidFunctionNoHandlerData>();
993   TestHandler<StartMsgTesterBoolFunctionNoHandlerData>();
994   TestHandler<StartMsgTesterVoidMethodNoHandlerData>();
995   TestHandler<StartMsgTesterBoolMethodNoHandlerData>();
996   TestHandler<StartMsgTesterVoidFunctionWithHandlerData>();
997   TestHandler<StartMsgTesterBoolFunctionWithHandlerData>();
998   TestHandler<StartMsgTesterVoidMethodWithHandlerData>();
999   TestHandler<StartMsgTesterBoolMethodWithHandlerData>();
1000 
1001   TestHandler<StringBufTesterVoidMethodNoHandlerDataNoHandle>();
1002   TestHandler<StringBufTesterVoidMethodNoHandlerDataWithHandle>();
1003   TestHandler<StringBufTesterVoidMethodWithHandlerDataNoHandle>();
1004   TestHandler<StringBufTesterVoidMethodWithHandlerDataWithHandle>();
1005   TestHandler<StringBufTesterVoidFunctionNoHandlerDataNoHandle>();
1006   TestHandler<StringBufTesterVoidFunctionNoHandlerDataWithHandle>();
1007   TestHandler<StringBufTesterVoidFunctionWithHandlerDataNoHandle>();
1008   TestHandler<StringBufTesterVoidFunctionWithHandlerDataWithHandle>();
1009   TestHandler<StringBufTesterSizeTMethodNoHandlerDataNoHandle>();
1010   TestHandler<StringBufTesterBoolMethodNoHandlerDataNoHandle>();
1011 
1012   TestMismatchedTypes();
1013 
1014   TestHandlerDataDestruction();
1015   TestIteration();
1016   TestArena();
1017 
1018   return 0;
1019 }
1020 
1021 }
1022