Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
aba42edd
Commit
aba42edd
authored
Jul 20, 2015
by
Joshua Haberman
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #604 from haberman/ruby-conformance
Added Ruby to conformance tests.
parents
58035596
c2c43a49
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
694 additions
and
579 deletions
+694
-579
Makefile.am
conformance/Makefile.am
+5
-2
conformance_ruby.rb
conformance/conformance_ruby.rb
+114
-0
conformance_test.h
conformance/conformance_test.h
+2
-0
conformance_test_runner.cc
conformance/conformance_test_runner.cc
+5
-3
failure_list_ruby.txt
conformance/failure_list_ruby.txt
+17
-0
defs.c
ruby/ext/google/protobuf_c/defs.c
+65
-3
encode_decode.c
ruby/ext/google/protobuf_c/encode_decode.c
+4
-2
protobuf.c
ruby/ext/google/protobuf_c/protobuf.c
+6
-0
protobuf.h
ruby/ext/google/protobuf_c/protobuf.h
+3
-0
upb.c
ruby/ext/google/protobuf_c/upb.c
+214
-269
upb.h
ruby/ext/google/protobuf_c/upb.h
+194
-266
protobuf.rb
ruby/lib/google/protobuf.rb
+9
-0
travis-test.sh
ruby/travis-test.sh
+16
-5
ruby_generated_code.rb
src/google/protobuf/compiler/ruby/ruby_generated_code.rb
+3
-3
ruby_generator.cc
src/google/protobuf/compiler/ruby/ruby_generator.cc
+21
-13
travis.sh
travis.sh
+16
-13
No files found.
conformance/Makefile.am
View file @
aba42edd
...
...
@@ -22,7 +22,7 @@ conformance_cpp_CPPFLAGS = -I$(top_srcdir)/src
if
USE_EXTERNAL_PROTOC
protoc_middleman
:
$(protoc_inputs)
$(PROTOC)
-I
$(srcdir)
--cpp_out
=
.
--java_out
=
.
$^
$(PROTOC)
-I
$(srcdir)
--cpp_out
=
.
--java_out
=
.
--ruby_out
=
.
$^
touch
protoc_middleman
else
...
...
@@ -31,7 +31,7 @@ else
# relative to srcdir, which may not be the same as the current directory when
# building out-of-tree.
protoc_middleman
:
$(top_srcdir)/src/protoc$(EXEEXT) $(protoc_inputs)
oldpwd
=
`
pwd
`
&&
(
cd
$(srcdir)
&&
$$
oldpwd/../src/protoc
$(EXEEXT)
-I
.
--cpp_out
=
$$
oldpwd
--java_out
=
$$
oldpwd
$(protoc_inputs)
)
oldpwd
=
`
pwd
`
&&
(
cd
$(srcdir)
&&
$$
oldpwd/../src/protoc
$(EXEEXT)
-I
.
--cpp_out
=
$$
oldpwd
--java_out
=
$$
oldpwd
--ruby_out
=
$$
oldpwd
$(protoc_inputs)
)
touch
protoc_middleman
endif
...
...
@@ -61,3 +61,6 @@ test_cpp: protoc_middleman conformance-test-runner conformance-cpp
test_java
:
protoc_middleman conformance-test-runner conformance-java
./conformance-test-runner ./conformance-java
test_ruby
:
protoc_middleman conformance-test-runner
RUBYLIB
=
../ruby/lib:. ./conformance-test-runner
--failure_list
failure_list_ruby.txt ./conformance_ruby.rb
conformance/conformance_ruby.rb
0 → 100755
View file @
aba42edd
#!/usr/bin/env ruby
#
# Protocol Buffers - Google's data interchange format
# Copyright 2008 Google Inc. All rights reserved.
# https://developers.google.com/protocol-buffers/
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions are
# met:
#
# * Redistributions of source code must retain the above copyright
# notice, this list of conditions and the following disclaimer.
# * Redistributions in binary form must reproduce the above
# copyright notice, this list of conditions and the following disclaimer
# in the documentation and/or other materials provided with the
# distribution.
# * Neither the name of Google Inc. nor the names of its
# contributors may be used to endorse or promote products derived from
# this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
require
'conformance'
$test_count
=
0
$verbose
=
false
def
do_test
(
request
)
test_message
=
Conformance
::
TestAllTypes
.
new
response
=
Conformance
::
ConformanceResponse
.
new
begin
case
request
.
payload
when
:protobuf_payload
begin
test_message
=
Conformance
::
TestAllTypes
.
decode
(
request
.
protobuf_payload
)
rescue
Google
::
Protobuf
::
ParseError
=>
err
response
.
parse_error
=
err
.
message
.
encode
(
'utf-8'
)
return
response
end
when
:json_payload
test_message
=
Conformance
::
TestAllTypes
.
decode_json
(
request
.
json_payload
)
when
nil
fail
"Request didn't have payload"
end
case
request
.
requested_output_format
when
:UNSPECIFIED
fail
'Unspecified output format'
when
:PROTOBUF
response
.
protobuf_payload
=
test_message
.
to_proto
when
:JSON
response
.
json_payload
=
test_message
.
to_json
end
rescue
StandardError
=>
err
response
.
runtime_error
=
err
.
message
.
encode
(
'utf-8'
)
end
response
end
# Returns true if the test ran successfully, false on legitimate EOF.
# If EOF is encountered in an unexpected place, raises IOError.
def
do_test_io
length_bytes
=
STDIN
.
read
(
4
)
return
false
if
length_bytes
.
nil?
length
=
length_bytes
.
unpack
(
'V'
).
first
serialized_request
=
STDIN
.
read
(
length
)
if
serialized_request
.
nil?
||
serialized_request
.
length
!=
length
fail
IOError
end
request
=
Conformance
::
ConformanceRequest
.
decode
(
serialized_request
)
response
=
do_test
(
request
)
serialized_response
=
Conformance
::
ConformanceResponse
.
encode
(
response
)
STDOUT
.
write
([
serialized_response
.
length
].
pack
(
'V'
))
STDOUT
.
write
(
serialized_response
)
STDOUT
.
flush
if
$verbose
STDERR
.
puts
(
"conformance-cpp: request={request.to_json}, "
\
"response={response.to_json}
\n
"
)
end
$test_count
+=
1
true
end
loop
do
unless
do_test_io
STDERR
.
puts
(
'conformance-cpp: received EOF from test runner '
\
"after
#{
$test_count
}
tests, exiting"
)
break
end
end
conformance/conformance_test.h
View file @
aba42edd
...
...
@@ -85,6 +85,8 @@ class ConformanceTestSuite {
public
:
ConformanceTestSuite
()
:
verbose_
(
false
)
{}
void
SetVerbose
(
bool
verbose
)
{
verbose_
=
verbose
;
}
// Sets the list of tests that are expected to fail when RunSuite() is called.
// RunSuite() will fail unless the set of failing tests is exactly the same
// as this list.
...
...
conformance/conformance_test_runner.cc
View file @
aba42edd
...
...
@@ -219,12 +219,16 @@ void ParseFailureList(const char *filename, vector<string>* failure_list) {
int
main
(
int
argc
,
char
*
argv
[])
{
int
arg
=
1
;
char
*
program
;
vector
<
string
>
failure_list
;
google
::
protobuf
::
ConformanceTestSuite
suite
;
for
(
int
arg
=
1
;
arg
<
argc
;
++
arg
)
{
if
(
strcmp
(
argv
[
arg
],
"--failure_list"
)
==
0
)
{
if
(
++
arg
==
argc
)
UsageError
();
vector
<
string
>
failure_list
;
ParseFailureList
(
argv
[
arg
],
&
failure_list
);
suite
.
SetFailureList
(
failure_list
);
}
else
if
(
strcmp
(
argv
[
arg
],
"--verbose"
)
==
0
)
{
suite
.
SetVerbose
(
true
);
}
else
if
(
argv
[
arg
][
0
]
==
'-'
)
{
fprintf
(
stderr
,
"Unknown option: %s
\n
"
,
argv
[
arg
]);
UsageError
();
...
...
@@ -238,8 +242,6 @@ int main(int argc, char *argv[]) {
}
ForkPipeRunner
runner
(
program
);
google
::
protobuf
::
ConformanceTestSuite
suite
;
suite
.
SetFailureList
(
failure_list
);
std
::
string
output
;
bool
ok
=
suite
.
RunSuite
(
&
runner
,
&
output
);
...
...
conformance/failure_list_ruby.txt
0 → 100644
View file @
aba42edd
JsonInput.HelloWorld.JsonOutput
JsonInput.HelloWorld.ProtobufOutput
ProtobufInput.PrematureEofBeforeUnknownValue.DOUBLE
ProtobufInput.PrematureEofBeforeUnknownValue.FIXED32
ProtobufInput.PrematureEofBeforeUnknownValue.FIXED64
ProtobufInput.PrematureEofBeforeUnknownValue.FLOAT
ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED32
ProtobufInput.PrematureEofBeforeUnknownValue.SFIXED64
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.BYTES
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.MESSAGE
ProtobufInput.PrematureEofInDelimitedDataForUnknownValue.STRING
ProtobufInput.PrematureEofInsideUnknownValue.DOUBLE
ProtobufInput.PrematureEofInsideUnknownValue.FIXED32
ProtobufInput.PrematureEofInsideUnknownValue.FIXED64
ProtobufInput.PrematureEofInsideUnknownValue.FLOAT
ProtobufInput.PrematureEofInsideUnknownValue.SFIXED32
ProtobufInput.PrematureEofInsideUnknownValue.SFIXED64
ruby/ext/google/protobuf_c/defs.c
View file @
aba42edd
...
...
@@ -548,7 +548,7 @@ upb_fieldtype_t ruby_to_fieldtype(VALUE type) {
#define CONVERT(upb, ruby) \
if (SYM2ID(type) == rb_intern( # ruby )) { \
return UPB_TYPE_ ## upb;
\
return UPB_TYPE_ ## upb; \
}
CONVERT
(
FLOAT
,
float
);
...
...
@@ -589,6 +589,68 @@ VALUE fieldtype_to_ruby(upb_fieldtype_t type) {
return
Qnil
;
}
upb_descriptortype_t
ruby_to_descriptortype
(
VALUE
type
)
{
if
(
TYPE
(
type
)
!=
T_SYMBOL
)
{
rb_raise
(
rb_eArgError
,
"Expected symbol for field type."
);
}
#define CONVERT(upb, ruby) \
if (SYM2ID(type) == rb_intern( # ruby )) { \
return UPB_DESCRIPTOR_TYPE_ ## upb; \
}
CONVERT
(
FLOAT
,
float
);
CONVERT
(
DOUBLE
,
double
);
CONVERT
(
BOOL
,
bool
);
CONVERT
(
STRING
,
string
);
CONVERT
(
BYTES
,
bytes
);
CONVERT
(
MESSAGE
,
message
);
CONVERT
(
GROUP
,
group
);
CONVERT
(
ENUM
,
enum
);
CONVERT
(
INT32
,
int32
);
CONVERT
(
INT64
,
int64
);
CONVERT
(
UINT32
,
uint32
);
CONVERT
(
UINT64
,
uint64
);
CONVERT
(
SINT32
,
sint32
);
CONVERT
(
SINT64
,
sint64
);
CONVERT
(
FIXED32
,
fixed32
);
CONVERT
(
FIXED64
,
fixed64
);
CONVERT
(
SFIXED32
,
sfixed32
);
CONVERT
(
SFIXED64
,
sfixed64
);
#undef CONVERT
rb_raise
(
rb_eArgError
,
"Unknown field type."
);
return
0
;
}
VALUE
descriptortype_to_ruby
(
upb_descriptortype_t
type
)
{
switch
(
type
)
{
#define CONVERT(upb, ruby) \
case UPB_DESCRIPTOR_TYPE_ ## upb : return ID2SYM(rb_intern( # ruby ));
CONVERT
(
FLOAT
,
float
);
CONVERT
(
DOUBLE
,
double
);
CONVERT
(
BOOL
,
bool
);
CONVERT
(
STRING
,
string
);
CONVERT
(
BYTES
,
bytes
);
CONVERT
(
MESSAGE
,
message
);
CONVERT
(
GROUP
,
group
);
CONVERT
(
ENUM
,
enum
);
CONVERT
(
INT32
,
int32
);
CONVERT
(
INT64
,
int64
);
CONVERT
(
UINT32
,
uint32
);
CONVERT
(
UINT64
,
uint64
);
CONVERT
(
SINT32
,
sint32
);
CONVERT
(
SINT64
,
sint64
);
CONVERT
(
FIXED32
,
fixed32
);
CONVERT
(
FIXED64
,
fixed64
);
CONVERT
(
SFIXED32
,
sfixed32
);
CONVERT
(
SFIXED64
,
sfixed64
);
#undef CONVERT
}
return
Qnil
;
}
/*
* call-seq:
* FieldDescriptor.type => type
...
...
@@ -604,7 +666,7 @@ VALUE FieldDescriptor_type(VALUE _self) {
if
(
!
upb_fielddef_typeisset
(
self
->
fielddef
))
{
return
Qnil
;
}
return
fieldtype_to_ruby
(
upb_fielddef_
type
(
self
->
fielddef
));
return
descriptortype_to_ruby
(
upb_fielddef_descriptor
type
(
self
->
fielddef
));
}
/*
...
...
@@ -617,7 +679,7 @@ VALUE FieldDescriptor_type(VALUE _self) {
VALUE
FieldDescriptor_type_set
(
VALUE
_self
,
VALUE
type
)
{
DEFINE_SELF
(
FieldDescriptor
,
self
,
_self
);
upb_fielddef
*
mut_def
=
check_field_notfrozen
(
self
->
fielddef
);
upb_fielddef_set
type
(
mut_def
,
ruby_to_field
type
(
type
));
upb_fielddef_set
descriptortype
(
mut_def
,
ruby_to_descriptor
type
(
type
));
return
Qnil
;
}
...
...
ruby/ext/google/protobuf_c/encode_decode.c
View file @
aba42edd
...
...
@@ -656,8 +656,10 @@ static bool env_error_func(void* ud, const upb_status* status) {
// Free the env -- rb_raise will longjmp up the stack past the encode/decode
// function so it would not otherwise have been freed.
stackenv_uninit
(
se
);
rb_raise
(
rb_eRuntimeError
,
se
->
ruby_error_template
,
upb_status_errmsg
(
status
));
// TODO(haberman): have a way to verify that this is actually a parse error,
// instead of just throwing "parse error" unconditionally.
rb_raise
(
cParseError
,
se
->
ruby_error_template
,
upb_status_errmsg
(
status
));
// Never reached: rb_raise() always longjmp()s up the stack, past all of our
// code, back to Ruby.
return
false
;
...
...
ruby/ext/google/protobuf_c/protobuf.c
View file @
aba42edd
...
...
@@ -39,6 +39,9 @@
// Ruby integers) to MessageDef/EnumDef instances (as Ruby values).
VALUE
upb_def_to_ruby_obj_map
;
VALUE
cError
;
VALUE
cParseError
;
void
add_def_obj
(
const
void
*
def
,
VALUE
value
)
{
rb_hash_aset
(
upb_def_to_ruby_obj_map
,
ULL2NUM
((
intptr_t
)
def
),
value
);
}
...
...
@@ -96,6 +99,9 @@ void Init_protobuf_c() {
RepeatedField_register
(
protobuf
);
Map_register
(
protobuf
);
cError
=
rb_const_get
(
protobuf
,
rb_intern
(
"Error"
));
cParseError
=
rb_const_get
(
protobuf
,
rb_intern
(
"ParseError"
));
rb_define_singleton_method
(
protobuf
,
"deep_copy"
,
Google_Protobuf_deep_copy
,
1
);
...
...
ruby/ext/google/protobuf_c/protobuf.h
View file @
aba42edd
...
...
@@ -161,6 +161,9 @@ extern VALUE cOneofBuilderContext;
extern
VALUE
cEnumBuilderContext
;
extern
VALUE
cBuilder
;
extern
VALUE
cError
;
extern
VALUE
cParseError
;
// We forward-declare all of the Ruby method implementations here because we
// sometimes call the methods directly across .c files, rather than going
// through Ruby's method dispatching (e.g. during message parse). It's cleaner
...
...
ruby/ext/google/protobuf_c/upb.c
View file @
aba42edd
// Amalgamated source file
#include "upb.h"
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2008-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include <stdlib.h>
...
...
@@ -1701,12 +1695,6 @@ upb_fielddef *upb_oneof_iter_field(const upb_oneof_iter *iter) {
void
upb_oneof_iter_setdone
(
upb_oneof_iter
*
iter
)
{
upb_inttable_iter_setdone
(
iter
);
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include <stdlib.h>
...
...
@@ -1980,14 +1968,9 @@ upb_alloc_func *upb_seededalloc_getallocfunc(upb_seededalloc *a) {
return
seeded_alloc
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* TODO(haberman): it's unclear whether a lot of the consistency checks should
* assert() or return false.
*/
** TODO(haberman): it's unclear whether a lot of the consistency checks should
** assert() or return false.
*/
#include <stdlib.h>
...
...
@@ -2668,24 +2651,21 @@ bool upb_byteshandler_setendstr(upb_byteshandler *h,
return
true
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Our key invariants are:
* 1. reference cycles never span groups
* 2. for ref2(to, from), we increment to's count iff group(from) != group(to)
*
* The previous two are how we avoid leaking cycles. Other important
* invariants are:
* 3. for mutable objects "from" and "to", if there exists a ref2(to, from)
* this implies group(from) == group(to). (In practice, what we implement
* is even stronger; "from" and "to" will share a group if there has *ever*
* been a ref2(to, from), but all that is necessary for correctness is the
* weaker one).
* 4. mutable and immutable objects are never in the same group.
*/
** upb::RefCounted Implementation
**
** Our key invariants are:
** 1. reference cycles never span groups
** 2. for ref2(to, from), we increment to's count iff group(from) != group(to)
**
** The previous two are how we avoid leaking cycles. Other important
** invariants are:
** 3. for mutable objects "from" and "to", if there exists a ref2(to, from)
** this implies group(from) == group(to). (In practice, what we implement
** is even stronger; "from" and "to" will share a group if there has *ever*
** been a ref2(to, from), but all that is necessary for correctness is the
** weaker one).
** 4. mutable and immutable objects are never in the same group.
*/
#include <setjmp.h>
...
...
@@ -3514,12 +3494,6 @@ bool upb_refcounted_freeze(upb_refcounted *const*roots, int n, upb_status *s,
}
return
freeze
(
roots
,
n
,
s
,
maxdepth
);
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include <stdlib.h>
...
...
@@ -3605,12 +3579,6 @@ const upb_shim_data *upb_shim_getdata(const upb_handlers *h, upb_selector_t s,
return
(
const
upb_shim_data
*
)
upb_handlers_gethandlerdata
(
h
,
s
);
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2008-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include <stdlib.h>
...
...
@@ -4041,13 +4009,10 @@ const upb_def *upb_symtab_iter_def(const upb_symtab_iter *iter) {
return
upb_value_getptr
(
upb_strtable_iter_value
(
&
iter
->
iter
));
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Implementation is heavily inspired by Lua's ltable.c.
*/
** upb_table Implementation
**
** Implementation is heavily inspired by Lua's ltable.c.
*/
#include <stdlib.h>
...
...
@@ -4931,12 +4896,6 @@ uint32_t MurmurHash2(const void * key, size_t len, uint32_t seed) {
#undef MIX
#endif
/* UPB_UNALIGNED_READS_OK */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include <errno.h>
#include <stdarg.h>
...
...
@@ -5860,17 +5819,12 @@ static upb_inttable reftables[212] = {
#endif
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2008-2009 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* XXX: The routines in this file that consume a string do not currently
* support having the string span buffers. In the future, as upb_sink and
* its buffering/sharing functionality evolve there should be an easy and
* idiomatic way of correctly handling this case. For now, we accept this
* limitation since we currently only parse descriptors from single strings.
*/
** XXX: The routines in this file that consume a string do not currently
** support having the string span buffers. In the future, as upb_sink and
** its buffering/sharing functionality evolve there should be an easy and
** idiomatic way of correctly handling this case. For now, we accept this
** limitation since we currently only parse descriptors from single strings.
*/
#include <errno.h>
...
...
@@ -6518,21 +6472,18 @@ const upb_handlers *upb_descreader_newhandlers(const void *owner) {
return
h
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Code to compile a upb::Handlers into bytecode for decoding a protobuf
* according to that specific schema and destination handlers.
*
* Compiling to bytecode is always the first step. If we are using the
* interpreted decoder we leave it as bytecode and interpret that. If we are
* using a JIT decoder we use a code generator to turn the bytecode into native
* code, LLVM IR, etc.
*
* Bytecode definition is in decoder.int.h.
*/
** protobuf decoder bytecode compiler
**
** Code to compile a upb::Handlers into bytecode for decoding a protobuf
** according to that specific schema and destination handlers.
**
** Compiling to bytecode is always the first step. If we are using the
** interpreted decoder we leave it as bytecode and interpret that. If we are
** using a JIT decoder we use a code generator to turn the bytecode into native
** code, LLVM IR, etc.
**
** Bytecode definition is in decoder.int.h.
*/
#include <stdarg.h>
...
...
@@ -7502,24 +7453,19 @@ void upb_pbdecodermethodopts_setlazy(upb_pbdecodermethodopts *opts, bool lazy) {
opts
->
lazy
=
lazy
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2008-2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* This file implements a VM for the interpreted (bytecode) decoder.
*
* Bytecode must previously have been generated using the bytecode compiler in
* compile_decoder.c. This decoder then walks through the bytecode op-by-op to
* parse the input.
*
* Decoding is fully resumable; we just keep a pointer to the current bytecode
* instruction and resume from there. A fair amount of the logic here is to
* handle the fact that values can span buffer seams and we have to be able to
* be capable of suspending/resuming from any byte in the stream. This
* sometimes requires keeping a few trailing bytes from the last buffer around
* in the "residual" buffer.
*/
** upb::Decoder (Bytecode Decoder VM)
**
** Bytecode must previously have been generated using the bytecode compiler in
** compile_decoder.c. This decoder then walks through the bytecode op-by-op to
** parse the input.
**
** Decoding is fully resumable; we just keep a pointer to the current bytecode
** instruction and resume from there. A fair amount of the logic here is to
** handle the fact that values can span buffer seams and we have to be able to
** be capable of suspending/resuming from any byte in the stream. This
** sometimes requires keeping a few trailing bytes from the last buffer around
** in the "residual" buffer.
*/
#include <inttypes.h>
#include <stddef.h>
...
...
@@ -8529,63 +8475,60 @@ bool upb_pbdecoder_setmaxnesting(upb_pbdecoder *d, size_t max) {
return
true
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Since we are implementing pure handlers (ie. without any out-of-band access
* to pre-computed lengths), we have to buffer all submessages before we can
* emit even their first byte.
*
* Not knowing the size of submessages also means we can't write a perfect
* zero-copy implementation, even with buffering. Lengths are stored as
* varints, which means that we don't know how many bytes to reserve for the
* length until we know what the length is.
*
* This leaves us with three main choices:
*
* 1. buffer all submessage data in a temporary buffer, then copy it exactly
* once into the output buffer.
*
* 2. attempt to buffer data directly into the output buffer, estimating how
* many bytes each length will take. When our guesses are wrong, use
* memmove() to grow or shrink the allotted space.
*
* 3. buffer directly into the output buffer, allocating a max length
* ahead-of-time for each submessage length. If we overallocated, we waste
* space, but no memcpy() or memmove() is required. This approach requires
* defining a maximum size for submessages and rejecting submessages that
* exceed that size.
*
* (2) and (3) have the potential to have better performance, but they are more
* complicated and subtle to implement:
*
* (3) requires making an arbitrary choice of the maximum message size; it
* wastes space when submessages are shorter than this and fails
* completely when they are longer. This makes it more finicky and
* requires configuration based on the input. It also makes it impossible
* to perfectly match the output of reference encoders that always use the
* optimal amount of space for each length.
*
* (2) requires guessing the the size upfront, and if multiple lengths are
* guessed wrong the minimum required number of memmove() operations may
* be complicated to compute correctly. Implemented properly, it may have
* a useful amortized or average cost, but more investigation is required
* to determine this and what the optimal algorithm is to achieve it.
*
* (1) makes you always pay for exactly one copy, but its implementation is
* the simplest and its performance is predictable.
*
* So for now, we implement (1) only. If we wish to optimize later, we should
* be able to do it without affecting users.
*
* The strategy is to buffer the segments of data that do *not* depend on
* unknown lengths in one buffer, and keep a separate buffer of segment pointers
* and lengths. When the top-level submessage ends, we can go beginning to end,
* alternating the writing of lengths with memcpy() of the rest of the data.
* At the top level though, no buffering is required.
*/
** upb::Encoder
**
** Since we are implementing pure handlers (ie. without any out-of-band access
** to pre-computed lengths), we have to buffer all submessages before we can
** emit even their first byte.
**
** Not knowing the size of submessages also means we can't write a perfect
** zero-copy implementation, even with buffering. Lengths are stored as
** varints, which means that we don't know how many bytes to reserve for the
** length until we know what the length is.
**
** This leaves us with three main choices:
**
** 1. buffer all submessage data in a temporary buffer, then copy it exactly
** once into the output buffer.
**
** 2. attempt to buffer data directly into the output buffer, estimating how
** many bytes each length will take. When our guesses are wrong, use
** memmove() to grow or shrink the allotted space.
**
** 3. buffer directly into the output buffer, allocating a max length
** ahead-of-time for each submessage length. If we overallocated, we waste
** space, but no memcpy() or memmove() is required. This approach requires
** defining a maximum size for submessages and rejecting submessages that
** exceed that size.
**
** (2) and (3) have the potential to have better performance, but they are more
** complicated and subtle to implement:
**
** (3) requires making an arbitrary choice of the maximum message size; it
** wastes space when submessages are shorter than this and fails
** completely when they are longer. This makes it more finicky and
** requires configuration based on the input. It also makes it impossible
** to perfectly match the output of reference encoders that always use the
** optimal amount of space for each length.
**
** (2) requires guessing the the size upfront, and if multiple lengths are
** guessed wrong the minimum required number of memmove() operations may
** be complicated to compute correctly. Implemented properly, it may have
** a useful amortized or average cost, but more investigation is required
** to determine this and what the optimal algorithm is to achieve it.
**
** (1) makes you always pay for exactly one copy, but its implementation is
** the simplest and its performance is predictable.
**
** So for now, we implement (1) only. If we wish to optimize later, we should
** be able to do it without affecting users.
**
** The strategy is to buffer the segments of data that do *not* depend on
** unknown lengths in one buffer, and keep a separate buffer of segment pointers
** and lengths. When the top-level submessage ends, we can go beginning to end,
** alternating the writing of lengths with memcpy() of the rest of the data.
** At the top level though, no buffering is required.
*/
#include <stdlib.h>
...
...
@@ -9095,12 +9038,6 @@ upb_pb_encoder *upb_pb_encoder_create(upb_env *env, const upb_handlers *h,
}
upb_sink
*
upb_pb_encoder_input
(
upb_pb_encoder
*
e
)
{
return
&
e
->
input_
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2010-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
#include <stdio.h>
...
...
@@ -9189,10 +9126,7 @@ bool upb_load_descriptor_file_into_symtab(upb_symtab *symtab, const char *fname,
return
success
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
* upb::pb::TextPrinter
*
* OPT: This is not optimized at all. It uses printf() which parses the format
* string every time, and it allocates memory for every put.
...
...
@@ -9529,12 +9463,6 @@ upb_sink *upb_textprinter_input(upb_textprinter *p) { return &p->input_; }
void
upb_textprinter_setsingleline
(
upb_textprinter
*
p
,
bool
single_line
)
{
p
->
single_line_
=
single_line
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2011 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
/* Index is descriptor type. */
...
...
@@ -9662,28 +9590,25 @@ upb_decoderet upb_vdecode_max8_wright(upb_decoderet r) {
#line 1 "upb/json/parser.rl"
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A parser that uses the Ragel State Machine Compiler to generate
* the finite automata.
*
* Ragel only natively handles regular languages, but we can manually
* program it a bit to handle context-free languages like JSON, by using
* the "fcall" and "fret" constructs.
*
* This parser can handle the basics, but needs several things to be fleshed
* out:
*
* - handling of unicode escape sequences (including high surrogate pairs).
* - properly check and report errors for unknown fields, stack overflow,
* improper array nesting (or lack of nesting).
* - handling of base64 sequences with padding characters.
* - handling of push-back (non-success returns from sink functions).
* - handling of keys/escape-sequences/etc that span input buffers.
*/
** upb::json::Parser (upb_json_parser)
**
** A parser that uses the Ragel State Machine Compiler to generate
** the finite automata.
**
** Ragel only natively handles regular languages, but we can manually
** program it a bit to handle context-free languages like JSON, by using
** the "fcall" and "fret" constructs.
**
** This parser can handle the basics, but needs several things to be fleshed
** out:
**
** - handling of unicode escape sequences (including high surrogate pairs).
** - properly check and report errors for unknown fields, stack overflow,
** improper array nesting (or lack of nesting).
** - handling of base64 sequences with padding characters.
** - handling of push-back (non-success returns from sink functions).
** - handling of keys/escape-sequences/etc that span input buffers.
*/
#include <stdio.h>
#include <stdint.h>
...
...
@@ -9731,7 +9656,7 @@ struct upb_json_parser {
upb_jsonparser_frame
*
top
;
upb_jsonparser_frame
*
limit
;
upb_status
*
status
;
upb_status
status
;
/* Ragel's internal parsing stack for the parsing state machine. */
int
current_state
;
...
...
@@ -9778,7 +9703,8 @@ static upb_selector_t parser_getsel(upb_json_parser *p) {
static
bool
check_stack
(
upb_json_parser
*
p
)
{
if
((
p
->
top
+
1
)
==
p
->
limit
)
{
upb_status_seterrmsg
(
p
->
status
,
"Nesting too deep"
);
upb_status_seterrmsg
(
&
p
->
status
,
"Nesting too deep"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -9860,9 +9786,10 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
char
output
[
3
];
if
(
limit
-
ptr
<
4
)
{
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"Base64 input for bytes field not a multiple of 4: %s"
,
upb_fielddef_name
(
p
->
top
->
f
));
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -9886,9 +9813,10 @@ static bool base64_push(upb_json_parser *p, upb_selector_t sel, const char *ptr,
otherchar:
if
(
nonbase64
(
ptr
[
0
])
||
nonbase64
(
ptr
[
1
])
||
nonbase64
(
ptr
[
2
])
||
nonbase64
(
ptr
[
3
])
)
{
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"Non-base64 characters in bytes field: %s"
,
upb_fielddef_name
(
p
->
top
->
f
));
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
if
(
ptr
[
2
]
==
'='
)
{
uint32_t
val
;
...
...
@@ -9926,10 +9854,11 @@ otherchar:
}
badpadding:
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"Incorrect base64 padding for field: %s (%.*s)"
,
upb_fielddef_name
(
p
->
top
->
f
),
4
,
ptr
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -9976,7 +9905,8 @@ static bool accumulate_realloc(upb_json_parser *p, size_t need) {
mem
=
upb_env_realloc
(
p
->
env
,
p
->
accumulate_buf
,
old_size
,
new_size
);
if
(
!
mem
)
{
upb_status_seterrmsg
(
p
->
status
,
"Out of memory allocating buffer."
);
upb_status_seterrmsg
(
&
p
->
status
,
"Out of memory allocating buffer."
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -9999,7 +9929,8 @@ static bool accumulate_append(upb_json_parser *p, const char *buf, size_t len,
}
if
(
!
checked_add
(
p
->
accumulated_len
,
len
,
&
need
))
{
upb_status_seterrmsg
(
p
->
status
,
"Integer overflow."
);
upb_status_seterrmsg
(
&
p
->
status
,
"Integer overflow."
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -10077,7 +10008,8 @@ static bool multipart_text(upb_json_parser *p, const char *buf, size_t len,
switch
(
p
->
multipart_state
)
{
case
MULTIPART_INACTIVE
:
upb_status_seterrmsg
(
p
->
status
,
"Internal error: unexpected state MULTIPART_INACTIVE"
);
&
p
->
status
,
"Internal error: unexpected state MULTIPART_INACTIVE"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
case
MULTIPART_ACCUMULATE
:
...
...
@@ -10336,7 +10268,8 @@ static bool parse_number(upb_json_parser *p) {
return
true
;
err:
upb_status_seterrf
(
p
->
status
,
"error parsing number: %s"
,
buf
);
upb_status_seterrf
(
&
p
->
status
,
"error parsing number: %s"
,
buf
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
multipart_end
(
p
);
return
false
;
}
...
...
@@ -10345,9 +10278,10 @@ static bool parser_putbool(upb_json_parser *p, bool val) {
bool
ok
;
if
(
upb_fielddef_type
(
p
->
top
->
f
)
!=
UPB_TYPE_BOOL
)
{
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"Boolean value specified for non-bool field: %s"
,
upb_fielddef_name
(
p
->
top
->
f
));
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -10398,9 +10332,10 @@ static bool start_stringval(upb_json_parser *p) {
multipart_startaccum
(
p
);
return
true
;
}
else
{
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"String specified for non-string/non-enum field: %s"
,
upb_fielddef_name
(
p
->
top
->
f
));
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
}
...
...
@@ -10438,7 +10373,8 @@ static bool end_stringval(upb_json_parser *p) {
upb_selector_t
sel
=
parser_getsel
(
p
);
upb_sink_putint32
(
&
p
->
top
->
sink
,
sel
,
int_val
);
}
else
{
upb_status_seterrf
(
p
->
status
,
"Enum value unknown: '%.*s'"
,
len
,
buf
);
upb_status_seterrf
(
&
p
->
status
,
"Enum value unknown: '%.*s'"
,
len
,
buf
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
}
break
;
...
...
@@ -10446,7 +10382,8 @@ static bool end_stringval(upb_json_parser *p) {
default:
assert
(
false
);
upb_status_seterrmsg
(
p
->
status
,
"Internal error in JSON decoder"
);
upb_status_seterrmsg
(
&
p
->
status
,
"Internal error in JSON decoder"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
ok
=
false
;
break
;
}
...
...
@@ -10476,7 +10413,8 @@ static bool parse_mapentry_key(upb_json_parser *p) {
p
->
top
->
f
=
upb_msgdef_itof
(
p
->
top
->
m
,
UPB_MAPENTRY_KEY
);
if
(
p
->
top
->
f
==
NULL
)
{
upb_status_seterrmsg
(
p
->
status
,
"mapentry message has no key"
);
upb_status_seterrmsg
(
&
p
->
status
,
"mapentry message has no key"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
switch
(
upb_fielddef_type
(
p
->
top
->
f
))
{
...
...
@@ -10499,8 +10437,9 @@ static bool parse_mapentry_key(upb_json_parser *p) {
return
false
;
}
}
else
{
upb_status_seterrmsg
(
p
->
status
,
upb_status_seterrmsg
(
&
p
->
status
,
"Map bool key not 'true' or 'false'"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
multipart_end
(
p
);
...
...
@@ -10518,7 +10457,8 @@ static bool parse_mapentry_key(upb_json_parser *p) {
break
;
}
default:
upb_status_seterrmsg
(
p
->
status
,
"Invalid field type for map key"
);
upb_status_seterrmsg
(
&
p
->
status
,
"Invalid field type for map key"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -10573,7 +10513,8 @@ static bool handle_mapentry(upb_json_parser *p) {
p
->
top
->
is_mapentry
=
true
;
/* set up to pop frame after value is parsed. */
p
->
top
->
mapfield
=
mapfield
;
if
(
p
->
top
->
f
==
NULL
)
{
upb_status_seterrmsg
(
p
->
status
,
"mapentry message has no value"
);
upb_status_seterrmsg
(
&
p
->
status
,
"mapentry message has no value"
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -10593,7 +10534,8 @@ static bool end_membername(upb_json_parser *p) {
if
(
!
f
)
{
/* TODO(haberman): Ignore unknown fields if requested/configured to do
* so. */
upb_status_seterrf
(
p
->
status
,
"No such field: %.*s
\n
"
,
(
int
)
len
,
buf
);
upb_status_seterrf
(
&
p
->
status
,
"No such field: %.*s
\n
"
,
(
int
)
len
,
buf
);
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -10669,9 +10611,10 @@ static bool start_subobject(upb_json_parser *p) {
return
true
;
}
else
{
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"Object specified for non-message/group field: %s"
,
upb_fielddef_name
(
p
->
top
->
f
));
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
}
...
...
@@ -10697,9 +10640,10 @@ static bool start_array(upb_json_parser *p) {
assert
(
p
->
top
->
f
);
if
(
!
upb_fielddef_isseq
(
p
->
top
->
f
))
{
upb_status_seterrf
(
p
->
status
,
upb_status_seterrf
(
&
p
->
status
,
"Array specified for non-repeated field: %s"
,
upb_fielddef_name
(
p
->
top
->
f
));
upb_env_reporterror
(
p
->
env
,
&
p
->
status
);
return
false
;
}
...
...
@@ -10736,7 +10680,11 @@ static void start_object(upb_json_parser *p) {
static
void
end_object
(
upb_json_parser
*
p
)
{
if
(
!
p
->
top
->
is_map
)
{
upb_status
status
;
upb_status_clear
(
&
status
);
upb_sink_endmsg
(
&
p
->
top
->
sink
,
&
status
);
if
(
!
upb_ok
(
&
status
))
{
upb_env_reporterror
(
p
->
env
,
&
status
);
}
}
}
...
...
@@ -10762,11 +10710,11 @@ static void end_object(upb_json_parser *p) {
* final state once, when the closing '"' is seen. */
#line 1
19
8 "upb/json/parser.rl"
#line 1
21
8 "upb/json/parser.rl"
#line 11
1
0 "upb/json/parser.c"
#line 11
3
0 "upb/json/parser.c"
static
const
char
_json_actions
[]
=
{
0
,
1
,
0
,
1
,
2
,
1
,
3
,
1
,
5
,
1
,
6
,
1
,
7
,
1
,
8
,
1
,
...
...
@@ -10915,7 +10863,7 @@ static const int json_en_value_machine = 27;
static
const
int
json_en_main
=
1
;
#line 12
0
1 "upb/json/parser.rl"
#line 12
2
1 "upb/json/parser.rl"
size_t
parse
(
void
*
closure
,
const
void
*
hd
,
const
char
*
buf
,
size_t
size
,
const
upb_bufhandle
*
handle
)
{
...
...
@@ -10937,7 +10885,7 @@ size_t parse(void *closure, const void *hd, const char *buf, size_t size,
capture_resume
(
parser
,
buf
);
#line 1
28
1 "upb/json/parser.c"
#line 1
30
1 "upb/json/parser.c"
{
int
_klen
;
unsigned
int
_trans
;
...
...
@@ -11012,118 +10960,118 @@ _match:
switch
(
*
_acts
++
)
{
case
0
:
#line 11
1
3 "upb/json/parser.rl"
#line 11
3
3 "upb/json/parser.rl"
{
p
--
;
{
cs
=
stack
[
--
top
];
goto
_again
;}
}
break
;
case
1
:
#line 11
1
4 "upb/json/parser.rl"
#line 11
3
4 "upb/json/parser.rl"
{
p
--
;
{
stack
[
top
++
]
=
cs
;
cs
=
10
;
goto
_again
;}
}
break
;
case
2
:
#line 11
1
8 "upb/json/parser.rl"
#line 11
3
8 "upb/json/parser.rl"
{
start_text
(
parser
,
p
);
}
break
;
case
3
:
#line 11
1
9 "upb/json/parser.rl"
#line 11
3
9 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
end_text
(
parser
,
p
));
}
break
;
case
4
:
#line 11
2
5 "upb/json/parser.rl"
#line 11
4
5 "upb/json/parser.rl"
{
start_hex
(
parser
);
}
break
;
case
5
:
#line 11
2
6 "upb/json/parser.rl"
#line 11
4
6 "upb/json/parser.rl"
{
hexdigit
(
parser
,
p
);
}
break
;
case
6
:
#line 11
2
7 "upb/json/parser.rl"
#line 11
4
7 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
end_hex
(
parser
));
}
break
;
case
7
:
#line 11
3
3 "upb/json/parser.rl"
#line 11
5
3 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
escape
(
parser
,
p
));
}
break
;
case
8
:
#line 11
3
9 "upb/json/parser.rl"
#line 11
5
9 "upb/json/parser.rl"
{
p
--
;
{
cs
=
stack
[
--
top
];
goto
_again
;}
}
break
;
case
9
:
#line 11
4
2 "upb/json/parser.rl"
#line 11
6
2 "upb/json/parser.rl"
{
{
stack
[
top
++
]
=
cs
;
cs
=
19
;
goto
_again
;}
}
break
;
case
10
:
#line 11
4
4 "upb/json/parser.rl"
#line 11
6
4 "upb/json/parser.rl"
{
p
--
;
{
stack
[
top
++
]
=
cs
;
cs
=
27
;
goto
_again
;}
}
break
;
case
11
:
#line 11
4
9 "upb/json/parser.rl"
#line 11
6
9 "upb/json/parser.rl"
{
start_member
(
parser
);
}
break
;
case
12
:
#line 11
5
0 "upb/json/parser.rl"
#line 11
7
0 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
end_membername
(
parser
));
}
break
;
case
13
:
#line 11
5
3 "upb/json/parser.rl"
#line 11
7
3 "upb/json/parser.rl"
{
end_member
(
parser
);
}
break
;
case
14
:
#line 11
5
9 "upb/json/parser.rl"
#line 11
7
9 "upb/json/parser.rl"
{
start_object
(
parser
);
}
break
;
case
15
:
#line 11
6
2 "upb/json/parser.rl"
#line 11
8
2 "upb/json/parser.rl"
{
end_object
(
parser
);
}
break
;
case
16
:
#line 11
6
8 "upb/json/parser.rl"
#line 11
8
8 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
start_array
(
parser
));
}
break
;
case
17
:
#line 11
7
2 "upb/json/parser.rl"
#line 11
9
2 "upb/json/parser.rl"
{
end_array
(
parser
);
}
break
;
case
18
:
#line 11
7
7 "upb/json/parser.rl"
#line 11
9
7 "upb/json/parser.rl"
{
start_number
(
parser
,
p
);
}
break
;
case
19
:
#line 11
7
8 "upb/json/parser.rl"
#line 11
9
8 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
end_number
(
parser
,
p
));
}
break
;
case
20
:
#line 1
18
0 "upb/json/parser.rl"
#line 1
20
0 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
start_stringval
(
parser
));
}
break
;
case
21
:
#line 1
18
1 "upb/json/parser.rl"
#line 1
20
1 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
end_stringval
(
parser
));
}
break
;
case
22
:
#line 1
18
3 "upb/json/parser.rl"
#line 1
20
3 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
parser_putbool
(
parser
,
true
));
}
break
;
case
23
:
#line 1
18
5 "upb/json/parser.rl"
#line 1
20
5 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
parser_putbool
(
parser
,
false
));
}
break
;
case
24
:
#line 1
18
7 "upb/json/parser.rl"
#line 1
20
7 "upb/json/parser.rl"
{
/* null value */
}
break
;
case
25
:
#line 1
18
9 "upb/json/parser.rl"
#line 1
20
9 "upb/json/parser.rl"
{
CHECK_RETURN_TOP
(
start_subobject
(
parser
));
}
break
;
case
26
:
#line 1
19
0 "upb/json/parser.rl"
#line 1
21
0 "upb/json/parser.rl"
{
end_subobject
(
parser
);
}
break
;
case
27
:
#line 1
19
5 "upb/json/parser.rl"
#line 1
21
5 "upb/json/parser.rl"
{
p
--
;
{
cs
=
stack
[
--
top
];
goto
_again
;}
}
break
;
#line 14
6
7 "upb/json/parser.c"
#line 14
8
7 "upb/json/parser.c"
}
}
...
...
@@ -11136,10 +11084,11 @@ _again:
_out:
{}
}
#line 12
2
2 "upb/json/parser.rl"
#line 12
4
2 "upb/json/parser.rl"
if
(
p
!=
pe
)
{
upb_status_seterrf
(
parser
->
status
,
"Parse error at %s
\n
"
,
p
);
upb_status_seterrf
(
&
parser
->
status
,
"Parse error at %s
\n
"
,
p
);
upb_env_reporterror
(
parser
->
env
,
&
parser
->
status
);
}
else
{
capture_suspend
(
parser
,
&
p
);
}
...
...
@@ -11176,19 +11125,20 @@ static void json_parser_reset(upb_json_parser *p) {
/* Emit Ragel initialization of the parser. */
#line 15
20
"upb/json/parser.c"
#line 15
41
"upb/json/parser.c"
{
cs
=
json_start
;
top
=
0
;
}
#line 12
61
"upb/json/parser.rl"
#line 12
82
"upb/json/parser.rl"
p
->
current_state
=
cs
;
p
->
parser_top
=
top
;
accumulate_clear
(
p
);
p
->
multipart_state
=
MULTIPART_INACTIVE
;
p
->
capture
=
NULL
;
p
->
accumulated
=
NULL
;
upb_status_clear
(
&
p
->
status
);
}
...
...
@@ -11214,8 +11164,8 @@ upb_json_parser *upb_json_parser_create(upb_env *env, upb_sink *output) {
upb_sink_reset
(
&
p
->
top
->
sink
,
output
->
handlers
,
output
->
closure
);
p
->
top
->
m
=
upb_handlers_msgdef
(
output
->
handlers
);
/* If this fails, uncomment and increase the value in parser.h.
* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
/* If this fails, uncomment and increase the value in parser.h.
*/
/
* fprintf(stderr, "%zd\n", upb_env_bytesallocated(env) - size_before); */
assert
(
upb_env_bytesallocated
(
env
)
-
size_before
<=
UPB_JSON_PARSER_SIZE
);
return
p
;
}
...
...
@@ -11224,14 +11174,9 @@ upb_bytessink *upb_json_parser_input(upb_json_parser *p) {
return
&
p
->
input_
;
}
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* This currently uses snprintf() to format primitives, and could be optimized
* further.
*/
** This currently uses snprintf() to format primitives, and could be optimized
** further.
*/
#include <stdlib.h>
...
...
ruby/ext/google/protobuf_c/upb.h
View file @
aba42edd
// Amalgamated source file
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Defs are upb's internal representation of the constructs that can appear
* in a .proto file:
*
* - upb_msgdef: describes a "message" construct.
* - upb_fielddef: describes a message field.
* - upb_enumdef: describes an enum.
* (TODO: definitions of services).
*
* Like upb_refcounted objects, defs are mutable only until frozen, and are
* only thread-safe once frozen.
*
* This is a mixed C/C++ interface that offers a full API to both languages.
* See the top-level README for more information.
*/
** Defs are upb's internal representation of the constructs that can appear
** in a .proto file:
**
** - upb::MessageDef (upb_msgdef): describes a "message" construct.
** - upb::FieldDef (upb_fielddef): describes a message field.
** - upb::EnumDef (upb_enumdef): describes an enum.
** - upb::OneofDef (upb_oneofdef): describes a oneof.
** - upb::Def (upb_def): base class of all the others.
**
** TODO: definitions of services.
**
** Like upb_refcounted objects, defs are mutable only until frozen, and are
** only thread-safe once frozen.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
#ifndef UPB_DEF_H_
#define UPB_DEF_H_
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A refcounting scheme that supports circular refs. It accomplishes this by
* partitioning the set of objects into groups such that no cycle spans groups;
* we can then reference-count the group as a whole and ignore refs within the
* group. When objects are mutable, these groups are computed very
* conservatively; we group any objects that have ever had a link between them.
* When objects are frozen, we compute strongly-connected components which
* allows us to be precise and only group objects that are actually cyclic.
*
* This is a mixed C/C++ interface that offers a full API to both languages.
* See the top-level README for more information.
*/
** upb::RefCounted (upb_refcounted)
**
** A refcounting scheme that supports circular refs. It accomplishes this by
** partitioning the set of objects into groups such that no cycle spans groups;
** we can then reference-count the group as a whole and ignore refs within the
** group. When objects are mutable, these groups are computed very
** conservatively; we group any objects that have ever had a link between them.
** When objects are frozen, we compute strongly-connected components which
** allows us to be precise and only group objects that are actually cyclic.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
#ifndef UPB_REFCOUNTED_H_
#define UPB_REFCOUNTED_H_
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* This header is INTERNAL-ONLY! Its interfaces are not public or stable!
* This file defines very fast int->upb_value (inttable) and string->upb_value
* (strtable) hash tables.
*
* The table uses chained scatter with Brent's variation (inspired by the Lua
* implementation of hash tables). The hash function for strings is Austin
* Appleby's "MurmurHash."
*
* The inttable uses uintptr_t as its key, which guarantees it can be used to
* store pointers or integers of at least 32 bits (upb isn't really useful on
* systems where sizeof(void*) < 4).
*
* The table must be homogenous (all values of the same type). In debug
* mode, we check this on insert and lookup.
*/
** upb_table
**
** This header is INTERNAL-ONLY! Its interfaces are not public or stable!
** This file defines very fast int->upb_value (inttable) and string->upb_value
** (strtable) hash tables.
**
** The table uses chained scatter with Brent's variation (inspired by the Lua
** implementation of hash tables). The hash function for strings is Austin
** Appleby's "MurmurHash."
**
** The inttable uses uintptr_t as its key, which guarantees it can be used to
** store pointers or integers of at least 32 bits (upb isn't really useful on
** systems where sizeof(void*) < 4).
**
** The table must be homogenous (all values of the same type). In debug
** mode, we check this on insert and lookup.
*/
#ifndef UPB_TABLE_H_
#define UPB_TABLE_H_
...
...
@@ -73,16 +65,11 @@
#include <stdint.h>
#include <string.h>
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* This file contains shared definitions that are widely used across upb.
*
* This is a mixed C/C++ interface that offers a full API to both languages.
* See the top-level README for more information.
*/
** This file contains shared definitions that are widely used across upb.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
#ifndef UPB_H_
#define UPB_H_
...
...
@@ -3006,25 +2993,20 @@ inline bool OneofDef::const_iterator::operator!=(
#endif
/* UPB_DEF_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2015 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* This file contains definitions of structs that should be considered private
* and NOT stable across versions of upb.
*
* The only reason they are declared here and not in .c files is to allow upb
* and the application (if desired) to embed statically-initialized instances
* of structures like defs.
*
* If you include this file, all guarantees of ABI compatibility go out the
* window! Any code that includes this file needs to recompile against the
* exact same version of upb that they are linking against.
*
* You also need to recompile if you change the value of the UPB_DEBUG_REFS
* flag.
*/
** This file contains definitions of structs that should be considered private
** and NOT stable across versions of upb.
**
** The only reason they are declared here and not in .c files is to allow upb
** and the application (if desired) to embed statically-initialized instances
** of structures like defs.
**
** If you include this file, all guarantees of ABI compatibility go out the
** window! Any code that includes this file needs to recompile against the
** exact same version of upb that they are linking against.
**
** You also need to recompile if you change the value of the UPB_DEBUG_REFS
** flag.
*/
#ifndef UPB_STATICINIT_H_
...
...
@@ -3181,25 +3163,22 @@ struct upb_symtab {
#endif
/* UPB_STATICINIT_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2010-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A upb_handlers is like a virtual table for a upb_msgdef. Each field of the
* message can have associated functions that will be called when we are
* parsing or visiting a stream of data. This is similar to how handlers work
* in SAX (the Simple API for XML).
*
* The handlers have no idea where the data is coming from, so a single set of
* handlers could be used with two completely different data sources (for
* example, a parser and a visitor over in-memory objects). This decoupling is
* the most important feature of upb, because it allows parsers and serializers
* to be highly reusable.
*
* This is a mixed C/C++ interface that offers a full API to both languages.
* See the top-level README for more information.
*/
** upb::Handlers (upb_handlers)
**
** A upb_handlers is like a virtual table for a upb_msgdef. Each field of the
** message can have associated functions that will be called when we are
** parsing or visiting a stream of data. This is similar to how handlers work
** in SAX (the Simple API for XML).
**
** The handlers have no idea where the data is coming from, so a single set of
** handlers could be used with two completely different data sources (for
** example, a parser and a visitor over in-memory objects). This decoupling is
** the most important feature of upb, because it allows parsers and serializers
** to be highly reusable.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
#ifndef UPB_HANDLERS_H
#define UPB_HANDLERS_H
...
...
@@ -3980,14 +3959,9 @@ uint32_t upb_handlers_selectorcount(const upb_fielddef *f);
UPB_END_EXTERN_C
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Inline definitions for handlers.h, which are particularly long and a bit
* tricky.
*/
** Inline definitions for handlers.h, which are particularly long and a bit
** tricky.
*/
#ifndef UPB_HANDLERS_INL_H_
#define UPB_HANDLERS_INL_H_
...
...
@@ -5128,21 +5102,18 @@ inline BytesHandler::~BytesHandler() {}
#endif
/* UPB_HANDLERS_H */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A upb::Environment provides a means for injecting malloc and an
* error-reporting callback into encoders/decoders. This allows them to be
* independent of nearly all assumptions about their actual environment.
*
* It is also a container for allocating the encoders/decoders themselves that
* insulates clients from knowing their actual size. This provides ABI
* compatibility even if the size of the objects change. And this allows the
* structure definitions to be in the .c files instead of the .h files, making
* the .h files smaller and more readable.
*/
** upb::Environment (upb_env)
**
** A upb::Environment provides a means for injecting malloc and an
** error-reporting callback into encoders/decoders. This allows them to be
** independent of nearly all assumptions about their actual environment.
**
** It is also a container for allocating the encoders/decoders themselves that
** insulates clients from knowing their actual size. This provides ABI
** compatibility even if the size of the objects change. And this allows the
** structure definitions to be in the .c files instead of the .h files, making
** the .h files smaller and more readable.
*/
#ifndef UPB_ENV_H_
...
...
@@ -5392,23 +5363,21 @@ inline upb_alloc_func *SeededAllocator::GetAllocationFunction() {
#endif
/* UPB_ENV_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2010-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A upb_sink is an object that binds a upb_handlers object to some runtime
* state. It is the object that can actually receive data via the upb_handlers
* interface.
*
* Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or
* thread-safe. You can create as many of them as you want, but each one may
* only be used in a single thread at a time.
*
* If we compare with class-based OOP, a you can think of a upb_def as an
* abstract base class, a upb_handlers as a concrete derived class, and a
* upb_sink as an object (class instance).
*/
** upb::Sink (upb_sink)
** upb::BytesSink (upb_bytessink)
**
** A upb_sink is an object that binds a upb_handlers object to some runtime
** state. It is the object that can actually receive data via the upb_handlers
** interface.
**
** Unlike upb_def and upb_handlers, upb_sink is never frozen, immutable, or
** thread-safe. You can create as many of them as you want, but each one may
** only be used in a single thread at a time.
**
** If we compare with class-based OOP, a you can think of a upb_def as an
** abstract base class, a upb_handlers as a concrete derived class, and a
** upb_sink as an object (class instance).
*/
#ifndef UPB_SINK_H
#define UPB_SINK_H
...
...
@@ -5921,21 +5890,16 @@ inline bool BufferSource::PutBuffer(const char *buf, size_t len,
#endif
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2013 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* For handlers that do very tiny, very simple operations, the function call
* overhead of calling a handler can be significant. This file allows the
* user to define handlers that do something very simple like store the value
* to memory and/or set a hasbit. JIT compilers can then special-case these
* handlers and emit specialized code for them instead of actually calling the
* handler.
*
* The functionality is very simple/limited right now but may expand to be able
* to call another function.
*/
** For handlers that do very tiny, very simple operations, the function call
** overhead of calling a handler can be significant. This file allows the
** user to define handlers that do something very simple like store the value
** to memory and/or set a hasbit. JIT compilers can then special-case these
** handlers and emit specialized code for them instead of actually calling the
** handler.
**
** The functionality is very simple/limited right now but may expand to be able
** to call another function.
*/
#ifndef UPB_SHIM_H
#define UPB_SHIM_H
...
...
@@ -5994,19 +5958,16 @@ inline const Shim::Data* Shim::GetData(const Handlers* h, Handlers::Selector s,
#endif
/* UPB_SHIM_H */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A symtab (symbol table) stores a name->def map of upb_defs. Clients could
* always create such tables themselves, but upb_symtab has logic for resolving
* symbolic references, and in particular, for keeping a whole set of consistent
* defs when replacing some subset of those defs. This logic is nontrivial.
*
* This is a mixed C/C++ interface that offers a full API to both languages.
* See the top-level README for more information.
*/
** upb::SymbolTable (upb_symtab)
**
** A symtab (symbol table) stores a name->def map of upb_defs. Clients could
** always create such tables themselves, but upb_symtab has logic for resolving
** symbolic references, and in particular, for keeping a whole set of consistent
** defs when replacing some subset of those defs. This logic is nontrivial.
**
** This is a mixed C/C++ interface that offers a full API to both languages.
** See the top-level README for more information.
*/
#ifndef UPB_SYMTAB_H_
#define UPB_SYMTAB_H_
...
...
@@ -6182,14 +6143,10 @@ inline bool SymbolTable::Add(
#endif
/* UPB_SYMTAB_H_ */
/*
* 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.
*/
** upb::descriptor::Reader (upb_descreader)
**
** Provides a way of building upb::Defs from data in descriptor.proto format.
*/
#ifndef UPB_DESCRIPTOR_H
#define UPB_DESCRIPTOR_H
...
...
@@ -7067,34 +7024,26 @@ inline upb::reffed_ptr<const upb::FieldDef> name_part() { RETURN_REFFED(upb::Fie
#endif
/* GOOGLE_PROTOBUF_DESCRIPTOR_UPB_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Internal-only definitions for the decoder.
*/
** Internal-only definitions for the decoder.
*/
#ifndef UPB_DECODER_INT_H_
#define UPB_DECODER_INT_H_
#include <stdlib.h>
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* upb::pb::Decoder implements a high performance, streaming, resumable decoder
* for the binary protobuf format.
*
* This interface works the same regardless of what decoder backend is being
* used. A client of this class does not need to know whether decoding is using
* a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default,
* it will always use the fastest available decoder. However, you can call
* set_allow_jit(false) to disable any JIT decoder that might be available.
* This is primarily useful for testing purposes.
*/
** upb::pb::Decoder
**
** A high performance, streaming, resumable decoder for the binary protobuf
** format.
**
** This interface works the same regardless of what decoder backend is being
** used. A client of this class does not need to know whether decoding is using
** a JITted decoder (DynASM, LLVM, etc) or an interpreted decoder. By default,
** it will always use the fastest available decoder. However, you can call
** set_allow_jit(false) to disable any JIT decoder that might be available.
** This is primarily useful for testing purposes.
*/
#ifndef UPB_DECODER_H_
#define UPB_DECODER_H_
...
...
@@ -7702,14 +7651,9 @@ UPB_INLINE void upb_pbdecoder_unpackdispatch(uint64_t dispatch, uint64_t *ofs,
#endif
/* UPB_DECODER_INT_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2011 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* A number of routines for varint manipulation (we keep them all around to
* have multiple approaches available for benchmarking).
*/
** A number of routines for varint manipulation (we keep them all around to
** have multiple approaches available for benchmarking).
*/
#ifndef UPB_VARINT_DECODER_H_
#define UPB_VARINT_DECODER_H_
...
...
@@ -7873,18 +7817,15 @@ UPB_INLINE uint64_t upb_vencode32(uint32_t val) {
#endif
/* UPB_VARINT_DECODER_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009-2010 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* Implements a set of upb_handlers that write protobuf data to the binary wire
* format.
*
* This encoder implementation does not have any access to any out-of-band or
* precomputed lengths for submessages, so it must buffer submessages internally
* before it can emit the first byte.
*/
** upb::pb::Encoder (upb_pb_encoder)
**
** Implements a set of upb_handlers that write protobuf data to the binary wire
** format.
**
** This encoder implementation does not have any access to any out-of-band or
** precomputed lengths for submessages, so it must buffer submessages internally
** before it can emit the first byte.
*/
#ifndef UPB_ENCODER_H_
#define UPB_ENCODER_H_
...
...
@@ -7966,29 +7907,24 @@ inline reffed_ptr<const Handlers> Encoder::NewHandlers(
#endif
/* UPB_ENCODER_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2011-2012 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* upb's core components like upb_decoder and upb_msg are carefully designed to
* avoid depending on each other for maximum orthogonality. In other words,
* you can use a upb_decoder to decode into *any* kind of structure; upb_msg is
* just one such structure. A upb_msg can be serialized/deserialized into any
* format, protobuf binary format is just one such format.
*
* However, for convenience we provide functions here for doing common
* operations like deserializing protobuf binary format into a upb_msg. The
* compromise is that this file drags in almost all of upb as a dependency,
* which could be undesirable if you're trying to use a trimmed-down build of
* upb.
*
* While these routines are convenient, they do not reuse any encoding/decoding
* state. For example, if a decoder is JIT-based, it will be re-JITted every
* time these functions are called. For this reason, if you are parsing lots
* of data and efficiency is an issue, these may not be the best functions to
* use (though they are useful for prototyping, before optimizing).
*/
** upb's core components like upb_decoder and upb_msg are carefully designed to
** avoid depending on each other for maximum orthogonality. In other words,
** you can use a upb_decoder to decode into *any* kind of structure; upb_msg is
** just one such structure. A upb_msg can be serialized/deserialized into any
** format, protobuf binary format is just one such format.
**
** However, for convenience we provide functions here for doing common
** operations like deserializing protobuf binary format into a upb_msg. The
** compromise is that this file drags in almost all of upb as a dependency,
** which could be undesirable if you're trying to use a trimmed-down build of
** upb.
**
** While these routines are convenient, they do not reuse any encoding/decoding
** state. For example, if a decoder is JIT-based, it will be re-JITted every
** time these functions are called. For this reason, if you are parsing lots
** of data and efficiency is an issue, these may not be the best functions to
** use (though they are useful for prototyping, before optimizing).
*/
#ifndef UPB_GLUE_H
#define UPB_GLUE_H
...
...
@@ -8047,11 +7983,10 @@ bool LoadDescriptorIntoSymtab(SymbolTable* s, const T& desc, Status* status) {
#endif
/* UPB_GLUE_H */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2009 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*/
** upb::pb::TextPrinter (upb_textprinter)
**
** Handlers for writing to protobuf text format.
*/
#ifndef UPB_TEXT_H_
#define UPB_TEXT_H_
...
...
@@ -8127,14 +8062,11 @@ inline reffed_ptr<const Handlers> TextPrinter::NewHandlers(
#endif
/* UPB_TEXT_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* upb::json::Parser can parse JSON according to a specific schema.
* Support for parsing arbitrary JSON (schema-less) will be added later.
*/
** upb::json::Parser (upb_json_parser)
**
** Parses JSON according to a specific schema.
** Support for parsing arbitrary JSON (schema-less) will be added later.
*/
#ifndef UPB_JSON_PARSER_H_
#define UPB_JSON_PARSER_H_
...
...
@@ -8156,7 +8088,7 @@ UPB_DECLARE_TYPE(upb::json::Parser, upb_json_parser)
* constructed. This hint may be an overestimate for some build configurations.
* But if the parser library is upgraded without recompiling the application,
* it may be an underestimate. */
#define UPB_JSON_PARSER_SIZE 3
568
#define UPB_JSON_PARSER_SIZE 3
704
#ifdef __cplusplus
...
...
@@ -8199,14 +8131,10 @@ inline BytesSink* Parser::input() {
#endif
/* UPB_JSON_PARSER_H_ */
/*
* upb - a minimalist implementation of protocol buffers.
*
* Copyright (c) 2014 Google Inc. See LICENSE for details.
* Author: Josh Haberman <jhaberman@gmail.com>
*
* upb::json::Printer allows you to create handlers that emit JSON
* according to a specific protobuf schema.
*/
** upb::json::Printer
**
** Handlers that emit JSON according to a specific protobuf schema.
*/
#ifndef UPB_JSON_TYPED_PRINTER_H_
#define UPB_JSON_TYPED_PRINTER_H_
...
...
ruby/lib/google/protobuf.rb
View file @
aba42edd
...
...
@@ -31,6 +31,15 @@
# require mixins before we hook them into the java & c code
require
'google/protobuf/message_exts'
# We define these before requiring the platform-specific modules.
# That way the module init can grab references to these.
module
Google
module
Protobuf
class
Error
<
StandardError
;
end
class
ParseError
<
Error
;
end
end
end
if
RUBY_PLATFORM
==
"java"
require
'json'
require
'google/protobuf_java'
...
...
ruby/travis-test.sh
View file @
aba42edd
...
...
@@ -5,11 +5,22 @@ set -e
test_version
()
{
version
=
$1
bash
--login
-c
\
"rvm install
$version
&& rvm use
$version
&&
\
which ruby &&
\
gem install bundler && bundle &&
\
rake test"
if
[
"
$version
"
==
"jruby"
]
;
then
# No conformance tests yet -- JRuby is too broken to run them.
bash
--login
-c
\
"rvm install
$version
&& rvm use
$version
&&
\
which ruby &&
\
gem install bundler && bundle &&
\
rake test"
else
bash
--login
-c
\
"rvm install
$version
&& rvm use
$version
&&
\
which ruby &&
\
gem install bundler && bundle &&
\
rake test &&
\
cd ../conformance &&
\
make test_ruby"
fi
}
test_version
$1
src/google/protobuf/compiler/ruby/ruby_generated_code.rb
View file @
aba42edd
...
...
@@ -13,7 +13,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
optional
:optional_double
,
:double
,
6
optional
:optional_float
,
:float
,
7
optional
:optional_string
,
:string
,
8
optional
:optional_bytes
,
:
string
,
9
optional
:optional_bytes
,
:
bytes
,
9
optional
:optional_enum
,
:enum
,
10
,
"A.B.C.TestEnum"
optional
:optional_msg
,
:message
,
11
,
"A.B.C.TestMessage"
repeated
:repeated_int32
,
:int32
,
21
...
...
@@ -24,7 +24,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
repeated
:repeated_double
,
:double
,
26
repeated
:repeated_float
,
:float
,
27
repeated
:repeated_string
,
:string
,
28
repeated
:repeated_bytes
,
:
string
,
29
repeated
:repeated_bytes
,
:
bytes
,
29
repeated
:repeated_enum
,
:enum
,
30
,
"A.B.C.TestEnum"
repeated
:repeated_msg
,
:message
,
31
,
"A.B.C.TestMessage"
map
:map_int32_string
,
:int32
,
:string
,
61
...
...
@@ -47,7 +47,7 @@ Google::Protobuf::DescriptorPool.generated_pool.build do
optional
:oneof_double
,
:double
,
46
optional
:oneof_float
,
:float
,
47
optional
:oneof_string
,
:string
,
48
optional
:oneof_bytes
,
:
string
,
49
optional
:oneof_bytes
,
:
bytes
,
49
optional
:oneof_enum
,
:enum
,
50
,
"A.B.C.TestEnum"
optional
:oneof_msg
,
:message
,
51
,
"A.B.C.TestMessage"
end
...
...
src/google/protobuf/compiler/ruby/ruby_generator.cc
View file @
aba42edd
...
...
@@ -47,7 +47,7 @@ namespace compiler {
namespace
ruby
{
// Forward decls.
std
::
string
IntToString
(
u
int32
value
);
std
::
string
IntToString
(
int32
value
);
std
::
string
StripDotProto
(
const
std
::
string
&
proto_file
);
std
::
string
LabelForField
(
google
::
protobuf
::
FieldDescriptor
*
field
);
std
::
string
TypeName
(
google
::
protobuf
::
FieldDescriptor
*
field
);
...
...
@@ -64,7 +64,7 @@ void GenerateEnumAssignment(
const
google
::
protobuf
::
EnumDescriptor
*
en
,
google
::
protobuf
::
io
::
Printer
*
printer
);
std
::
string
IntToString
(
u
int32
value
)
{
std
::
string
IntToString
(
int32
value
)
{
std
::
ostringstream
os
;
os
<<
value
;
return
os
.
str
();
...
...
@@ -85,17 +85,25 @@ std::string LabelForField(const google::protobuf::FieldDescriptor* field) {
}
std
::
string
TypeName
(
const
google
::
protobuf
::
FieldDescriptor
*
field
)
{
switch
(
field
->
cpp_type
())
{
case
FieldDescriptor
:
:
CPPTYPE_INT32
:
return
"int32"
;
case
FieldDescriptor
:
:
CPPTYPE_INT64
:
return
"int64"
;
case
FieldDescriptor
:
:
CPPTYPE_UINT32
:
return
"uint32"
;
case
FieldDescriptor
:
:
CPPTYPE_UINT64
:
return
"uint64"
;
case
FieldDescriptor
:
:
CPPTYPE_DOUBLE
:
return
"double"
;
case
FieldDescriptor
:
:
CPPTYPE_FLOAT
:
return
"float"
;
case
FieldDescriptor
:
:
CPPTYPE_BOOL
:
return
"bool"
;
case
FieldDescriptor
:
:
CPPTYPE_ENUM
:
return
"enum"
;
case
FieldDescriptor
:
:
CPPTYPE_STRING
:
return
"string"
;
case
FieldDescriptor
:
:
CPPTYPE_MESSAGE
:
return
"message"
;
switch
(
field
->
type
())
{
case
FieldDescriptor
:
:
TYPE_INT32
:
return
"int32"
;
case
FieldDescriptor
:
:
TYPE_INT64
:
return
"int64"
;
case
FieldDescriptor
:
:
TYPE_UINT32
:
return
"uint32"
;
case
FieldDescriptor
:
:
TYPE_UINT64
:
return
"uint64"
;
case
FieldDescriptor
:
:
TYPE_SINT32
:
return
"sint32"
;
case
FieldDescriptor
:
:
TYPE_SINT64
:
return
"sint64"
;
case
FieldDescriptor
:
:
TYPE_FIXED32
:
return
"fixed32"
;
case
FieldDescriptor
:
:
TYPE_FIXED64
:
return
"fixed64"
;
case
FieldDescriptor
:
:
TYPE_SFIXED32
:
return
"sfixed32"
;
case
FieldDescriptor
:
:
TYPE_SFIXED64
:
return
"sfixed64"
;
case
FieldDescriptor
:
:
TYPE_DOUBLE
:
return
"double"
;
case
FieldDescriptor
:
:
TYPE_FLOAT
:
return
"float"
;
case
FieldDescriptor
:
:
TYPE_BOOL
:
return
"bool"
;
case
FieldDescriptor
:
:
TYPE_ENUM
:
return
"enum"
;
case
FieldDescriptor
:
:
TYPE_STRING
:
return
"string"
;
case
FieldDescriptor
:
:
TYPE_BYTES
:
return
"bytes"
;
case
FieldDescriptor
:
:
TYPE_MESSAGE
:
return
"message"
;
case
FieldDescriptor
:
:
TYPE_GROUP
:
return
"group"
;
default
:
assert
(
false
);
return
""
;
}
}
...
...
travis.sh
View file @
aba42edd
...
...
@@ -8,10 +8,16 @@
# .travis.yml uses matrix.exclude to block the cases where app-get can't be
# use to install things.
build_cpp
()
{
# For when some other test needs the C++ main build, including protoc and
# libprotobuf.
internal_build_cpp
()
{
./autogen.sh
./configure
make
-j2
}
build_cpp
()
{
internal_build_cpp
make check
-j2
cd
conformance
&&
make test_cpp
&&
cd
..
}
...
...
@@ -62,18 +68,14 @@ use_java() {
build_java
()
{
# Java build needs `protoc`.
./autogen.sh
./configure
make
-j2
internal_build_cpp
cd
java
&&
mvn
test
&&
cd
..
cd
conformance
&&
make test_java
&&
cd
..
}
build_javanano
()
{
# Java build needs `protoc`.
./autogen.sh
./configure
make
-j2
internal_build_cpp
cd
javanano
&&
mvn
test
&&
cd
..
}
...
...
@@ -104,9 +106,7 @@ build_javanano_oracle7() {
}
build_python
()
{
./autogen.sh
./configure
make
-j2
internal_build_cpp
cd
python
python setup.py build
python setup.py
test
...
...
@@ -116,9 +116,7 @@ build_python() {
}
build_python_cpp
()
{
./autogen.sh
./configure
make
-j2
internal_build_cpp
export
LD_LIBRARY_PATH
=
../src/.libs
# for Linux
export
DYLD_LIBRARY_PATH
=
../src/.libs
# for OS X
cd
python
...
...
@@ -130,18 +128,23 @@ build_python_cpp() {
}
build_ruby19
()
{
internal_build_cpp
# For conformance tests.
cd
ruby
&&
bash travis-test.sh ruby-1.9
&&
cd
..
}
build_ruby20
()
{
internal_build_cpp
# For conformance tests.
cd
ruby
&&
bash travis-test.sh ruby-2.0
&&
cd
..
}
build_ruby21
()
{
internal_build_cpp
# For conformance tests.
cd
ruby
&&
bash travis-test.sh ruby-2.1
&&
cd
..
}
build_ruby22
()
{
internal_build_cpp
# For conformance tests.
cd
ruby
&&
bash travis-test.sh ruby-2.2
&&
cd
..
}
build_jruby
()
{
internal_build_cpp
# For conformance tests.
cd
ruby
&&
bash travis-test.sh jruby
&&
cd
..
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment