commit
322e720fe6
269 changed files with 16069 additions and 7007 deletions
@ -1,14 +1,18 @@ |
||||
mergeable: |
||||
pull_requests: |
||||
label: |
||||
or: |
||||
- and: |
||||
and: |
||||
- must_exclude: |
||||
regex: '^disposition/DO NOT MERGE' |
||||
message: 'Pull request marked not mergeable' |
||||
- or: |
||||
- and: |
||||
- must_include: |
||||
regex: 'release notes: yes' |
||||
message: 'Please include release note: yes' |
||||
- must_include: |
||||
regex: '^lang\/' |
||||
message: 'Please include a language label' |
||||
- must_include: |
||||
regex: 'release notes: yes' |
||||
message: 'Please include release note: yes' |
||||
- must_include: |
||||
regex: '^lang\/' |
||||
message: 'Please include a language label' |
||||
- must_include: |
||||
regex: 'release notes: no' |
||||
message: 'Please include release note: no' |
||||
regex: 'release notes: no' |
||||
message: 'Please include release note: no' |
||||
|
@ -0,0 +1,59 @@ |
||||
# gRPC Bazel BUILD file. |
||||
# |
||||
# Copyright 2019 The gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
|
||||
load("@grpc_python_dependencies//:requirements.bzl", "requirement") |
||||
load("@org_pubref_rules_protobuf//python:rules.bzl", "py_proto_library") |
||||
|
||||
py_proto_library( |
||||
name = "prime_proto", |
||||
protos = ["prime.proto",], |
||||
deps = [requirement("protobuf")], |
||||
) |
||||
|
||||
py_binary( |
||||
name = "client", |
||||
testonly = 1, |
||||
srcs = ["client.py"], |
||||
deps = [ |
||||
"//src/python/grpcio/grpc:grpcio", |
||||
":prime_proto", |
||||
], |
||||
default_python_version = "PY3", |
||||
) |
||||
|
||||
py_binary( |
||||
name = "server", |
||||
testonly = 1, |
||||
srcs = ["server.py"], |
||||
deps = [ |
||||
"//src/python/grpcio/grpc:grpcio", |
||||
":prime_proto" |
||||
] + select({ |
||||
"//conditions:default": [requirement("futures")], |
||||
"//:python3": [], |
||||
}), |
||||
default_python_version = "PY3", |
||||
) |
||||
|
||||
py_test( |
||||
name = "test/_multiprocessing_example_test", |
||||
srcs = ["test/_multiprocessing_example_test.py"], |
||||
data = [ |
||||
":client", |
||||
":server" |
||||
], |
||||
size = "small", |
||||
) |
@ -0,0 +1,67 @@ |
||||
## Multiprocessing with gRPC Python |
||||
|
||||
Multiprocessing allows application developers to sidestep the Python global |
||||
interpreter lock and achieve true concurrency on multicore systems. |
||||
Unfortunately, using multiprocessing and gRPC Python is not yet as simple as |
||||
instantiating your server with a `futures.ProcessPoolExecutor`. |
||||
|
||||
The library is implemented as a C extension, maintaining much of the state that |
||||
drives the system in native code. As such, upon calling |
||||
[`fork`](http://man7.org/linux/man-pages/man2/fork.2.html), much of the |
||||
state copied into the child process is invalid, leading to hangs and crashes. |
||||
|
||||
However, calling `fork` without `exec` in your python process is supported |
||||
*before* any gRPC servers have been instantiated. Application developers can |
||||
take advantage of this to parallelize their CPU-intensive operations. |
||||
|
||||
## Calculating Prime Numbers with Multiple Processes |
||||
|
||||
This example calculates the first 10,000 prime numbers as an RPC. We instantiate |
||||
one server per subprocess, balancing requests between the servers using the |
||||
[`SO_REUSEPORT`](https://lwn.net/Articles/542629/) socket option. Note that this |
||||
option is not available in `manylinux1` distributions, which are, as of the time |
||||
of writing, the only gRPC Python wheels available on PyPI. To take advantage of this |
||||
feature, you'll need to build from source, either using bazel (as we do for |
||||
these examples) or via pip, using `pip install grpcio --no-binary grpcio`. |
||||
|
||||
```python |
||||
_PROCESS_COUNT = multiprocessing.cpu_count() |
||||
``` |
||||
|
||||
On the server side, we detect the number of CPUs available on the system and |
||||
spawn exactly that many child processes. If we spin up fewer, we won't be taking |
||||
full advantage of the hardware resources available. |
||||
|
||||
## Running the Example |
||||
|
||||
To run the server, |
||||
[ensure `bazel` is installed](https://docs.bazel.build/versions/master/install.html) |
||||
and run: |
||||
|
||||
``` |
||||
bazel run //examples/python/multiprocessing:server & |
||||
``` |
||||
|
||||
Note the address at which the server is running. For example, |
||||
|
||||
``` |
||||
... |
||||
[PID 107153] Binding to '[::]:33915' |
||||
[PID 107507] Starting new server. |
||||
[PID 107508] Starting new server. |
||||
... |
||||
``` |
||||
|
||||
Note that several servers have been started, each with its own PID. |
||||
|
||||
Now, start the client by running |
||||
|
||||
``` |
||||
bazel run //examples/python/multiprocessing:client -- [SERVER_ADDRESS] |
||||
``` |
||||
|
||||
For example, |
||||
|
||||
``` |
||||
bazel run //examples/python/multiprocessing:client -- [::]:33915 |
||||
``` |
@ -0,0 +1,95 @@ |
||||
# Copyright 2019 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
"""An example of multiprocessing concurrency with gRPC.""" |
||||
|
||||
from __future__ import absolute_import |
||||
from __future__ import division |
||||
from __future__ import print_function |
||||
|
||||
import argparse |
||||
import atexit |
||||
import logging |
||||
import multiprocessing |
||||
import operator |
||||
import sys |
||||
|
||||
import grpc |
||||
|
||||
from examples.python.multiprocessing import prime_pb2 |
||||
from examples.python.multiprocessing import prime_pb2_grpc |
||||
|
||||
_PROCESS_COUNT = 8 |
||||
_MAXIMUM_CANDIDATE = 10000 |
||||
|
||||
# Each worker process initializes a single channel after forking. |
||||
# It's regrettable, but to ensure that each subprocess only has to instantiate |
||||
# a single channel to be reused across all RPCs, we use globals. |
||||
_worker_channel_singleton = None |
||||
_worker_stub_singleton = None |
||||
|
||||
_LOGGER = logging.getLogger(__name__) |
||||
|
||||
|
||||
def _shutdown_worker(): |
||||
_LOGGER.info('Shutting worker process down.') |
||||
if _worker_channel_singleton is not None: |
||||
_worker_channel_singleton.stop() |
||||
|
||||
|
||||
def _initialize_worker(server_address): |
||||
global _worker_channel_singleton # pylint: disable=global-statement |
||||
global _worker_stub_singleton # pylint: disable=global-statement |
||||
_LOGGER.info('Initializing worker process.') |
||||
_worker_channel_singleton = grpc.insecure_channel(server_address) |
||||
_worker_stub_singleton = prime_pb2_grpc.PrimeCheckerStub( |
||||
_worker_channel_singleton) |
||||
atexit.register(_shutdown_worker) |
||||
|
||||
|
||||
def _run_worker_query(primality_candidate): |
||||
_LOGGER.info('Checking primality of %s.', primality_candidate) |
||||
return _worker_stub_singleton.check( |
||||
prime_pb2.PrimeCandidate(candidate=primality_candidate)) |
||||
|
||||
|
||||
def _calculate_primes(server_address): |
||||
worker_pool = multiprocessing.Pool( |
||||
processes=_PROCESS_COUNT, |
||||
initializer=_initialize_worker, |
||||
initargs=(server_address,)) |
||||
check_range = range(2, _MAXIMUM_CANDIDATE) |
||||
primality = worker_pool.map(_run_worker_query, check_range) |
||||
primes = zip(check_range, map(operator.attrgetter('isPrime'), primality)) |
||||
return tuple(primes) |
||||
|
||||
|
||||
def main(): |
||||
msg = 'Determine the primality of the first {} integers.'.format( |
||||
_MAXIMUM_CANDIDATE) |
||||
parser = argparse.ArgumentParser(description=msg) |
||||
parser.add_argument( |
||||
'server_address', |
||||
help='The address of the server (e.g. localhost:50051)') |
||||
args = parser.parse_args() |
||||
primes = _calculate_primes(args.server_address) |
||||
print(primes) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
handler = logging.StreamHandler(sys.stdout) |
||||
formatter = logging.Formatter('[PID %(process)d] %(message)s') |
||||
handler.setFormatter(formatter) |
||||
_LOGGER.addHandler(handler) |
||||
_LOGGER.setLevel(logging.INFO) |
||||
main() |
@ -0,0 +1,35 @@ |
||||
// Copyright 2019 gRPC authors. |
||||
// |
||||
// Licensed under the Apache License, Version 2.0 (the "License"); |
||||
// you may not use this file except in compliance with the License. |
||||
// You may obtain a copy of the License at |
||||
// |
||||
// http://www.apache.org/licenses/LICENSE-2.0 |
||||
// |
||||
// Unless required by applicable law or agreed to in writing, software |
||||
// distributed under the License is distributed on an "AS IS" BASIS, |
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
// See the License for the specific language governing permissions and |
||||
// limitations under the License. |
||||
|
||||
syntax = "proto3"; |
||||
|
||||
package prime; |
||||
|
||||
// A candidate integer for primality testing. |
||||
message PrimeCandidate { |
||||
// The candidate. |
||||
int64 candidate = 1; |
||||
} |
||||
|
||||
// The primality of the requested integer candidate. |
||||
message Primality { |
||||
// Is the candidate prime? |
||||
bool isPrime = 1; |
||||
} |
||||
|
||||
// Service to check primality. |
||||
service PrimeChecker { |
||||
// Determines the primality of an integer. |
||||
rpc check (PrimeCandidate) returns (Primality) {} |
||||
} |
@ -0,0 +1,123 @@ |
||||
# Copyright 2019 gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
"""An example of multiprocess concurrency with gRPC.""" |
||||
|
||||
from __future__ import absolute_import |
||||
from __future__ import division |
||||
from __future__ import print_function |
||||
|
||||
from concurrent import futures |
||||
import contextlib |
||||
import datetime |
||||
import logging |
||||
import math |
||||
import multiprocessing |
||||
import time |
||||
import socket |
||||
import sys |
||||
|
||||
import grpc |
||||
|
||||
from examples.python.multiprocessing import prime_pb2 |
||||
from examples.python.multiprocessing import prime_pb2_grpc |
||||
|
||||
_LOGGER = logging.getLogger(__name__) |
||||
|
||||
_ONE_DAY = datetime.timedelta(days=1) |
||||
_PROCESS_COUNT = multiprocessing.cpu_count() |
||||
_THREAD_CONCURRENCY = _PROCESS_COUNT |
||||
|
||||
|
||||
def is_prime(n): |
||||
for i in range(2, int(math.ceil(math.sqrt(n)))): |
||||
if n % i == 0: |
||||
return False |
||||
else: |
||||
return True |
||||
|
||||
|
||||
class PrimeChecker(prime_pb2_grpc.PrimeCheckerServicer): |
||||
|
||||
def check(self, request, context): |
||||
_LOGGER.info('Determining primality of %s', request.candidate) |
||||
return prime_pb2.Primality(isPrime=is_prime(request.candidate)) |
||||
|
||||
|
||||
def _wait_forever(server): |
||||
try: |
||||
while True: |
||||
time.sleep(_ONE_DAY.total_seconds()) |
||||
except KeyboardInterrupt: |
||||
server.stop(None) |
||||
|
||||
|
||||
def _run_server(bind_address): |
||||
"""Start a server in a subprocess.""" |
||||
_LOGGER.info('Starting new server.') |
||||
options = (('grpc.so_reuseport', 1),) |
||||
|
||||
# WARNING: This example takes advantage of SO_REUSEPORT. Due to the |
||||
# limitations of manylinux1, none of our precompiled Linux wheels currently |
||||
# support this option. (https://github.com/grpc/grpc/issues/18210). To take |
||||
# advantage of this feature, install from source with |
||||
# `pip install grpcio --no-binary grpcio`. |
||||
|
||||
server = grpc.server( |
||||
futures.ThreadPoolExecutor(max_workers=_THREAD_CONCURRENCY,), |
||||
options=options) |
||||
prime_pb2_grpc.add_PrimeCheckerServicer_to_server(PrimeChecker(), server) |
||||
server.add_insecure_port(bind_address) |
||||
server.start() |
||||
_wait_forever(server) |
||||
|
||||
|
||||
@contextlib.contextmanager |
||||
def _reserve_port(): |
||||
"""Find and reserve a port for all subprocesses to use.""" |
||||
sock = socket.socket(socket.AF_INET6, socket.SOCK_STREAM) |
||||
sock.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT, 1) |
||||
if sock.getsockopt(socket.SOL_SOCKET, socket.SO_REUSEPORT) != 1: |
||||
raise RuntimeError("Failed to set SO_REUSEPORT.") |
||||
sock.bind(('', 0)) |
||||
try: |
||||
yield sock.getsockname()[1] |
||||
finally: |
||||
sock.close() |
||||
|
||||
|
||||
def main(): |
||||
with _reserve_port() as port: |
||||
bind_address = 'localhost:{}'.format(port) |
||||
_LOGGER.info("Binding to '%s'", bind_address) |
||||
sys.stdout.flush() |
||||
workers = [] |
||||
for _ in range(_PROCESS_COUNT): |
||||
# NOTE: It is imperative that the worker subprocesses be forked before |
||||
# any gRPC servers start up. See |
||||
# https://github.com/grpc/grpc/issues/16001 for more details. |
||||
worker = multiprocessing.Process( |
||||
target=_run_server, args=(bind_address,)) |
||||
worker.start() |
||||
workers.append(worker) |
||||
for worker in workers: |
||||
worker.join() |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
handler = logging.StreamHandler(sys.stdout) |
||||
formatter = logging.Formatter('[PID %(process)d] %(message)s') |
||||
handler.setFormatter(formatter) |
||||
_LOGGER.addHandler(handler) |
||||
_LOGGER.setLevel(logging.INFO) |
||||
main() |
@ -0,0 +1,74 @@ |
||||
# Copyright 2019 the gRPC authors. |
||||
# |
||||
# Licensed under the Apache License, Version 2.0 (the "License"); |
||||
# you may not use this file except in compliance with the License. |
||||
# You may obtain a copy of the License at |
||||
# |
||||
# http://www.apache.org/licenses/LICENSE-2.0 |
||||
# |
||||
# Unless required by applicable law or agreed to in writing, software |
||||
# distributed under the License is distributed on an "AS IS" BASIS, |
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
# See the License for the specific language governing permissions and |
||||
# limitations under the License. |
||||
"""Test for multiprocessing example.""" |
||||
|
||||
import ast |
||||
import logging |
||||
import math |
||||
import os |
||||
import re |
||||
import subprocess |
||||
import tempfile |
||||
import unittest |
||||
|
||||
_BINARY_DIR = os.path.realpath( |
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), '..')) |
||||
_SERVER_PATH = os.path.join(_BINARY_DIR, 'server') |
||||
_CLIENT_PATH = os.path.join(_BINARY_DIR, 'client') |
||||
|
||||
|
||||
def is_prime(n): |
||||
for i in range(2, int(math.ceil(math.sqrt(n)))): |
||||
if n % i == 0: |
||||
return False |
||||
else: |
||||
return True |
||||
|
||||
|
||||
def _get_server_address(server_stream): |
||||
while True: |
||||
server_stream.seek(0) |
||||
line = server_stream.readline() |
||||
while line: |
||||
matches = re.search('Binding to \'(.+)\'', line) |
||||
if matches is not None: |
||||
return matches.groups()[0] |
||||
line = server_stream.readline() |
||||
|
||||
|
||||
class MultiprocessingExampleTest(unittest.TestCase): |
||||
|
||||
def test_multiprocessing_example(self): |
||||
server_stdout = tempfile.TemporaryFile(mode='r') |
||||
server_process = subprocess.Popen((_SERVER_PATH,), stdout=server_stdout) |
||||
server_address = _get_server_address(server_stdout) |
||||
client_stdout = tempfile.TemporaryFile(mode='r') |
||||
client_process = subprocess.Popen( |
||||
( |
||||
_CLIENT_PATH, |
||||
server_address, |
||||
), stdout=client_stdout) |
||||
client_process.wait() |
||||
server_process.terminate() |
||||
client_stdout.seek(0) |
||||
results = ast.literal_eval(client_stdout.read().strip().split('\n')[-1]) |
||||
values = tuple(result[0] for result in results) |
||||
self.assertSequenceEqual(range(2, 10000), values) |
||||
for result in results: |
||||
self.assertEqual(is_prime(result[0]), result[1]) |
||||
|
||||
|
||||
if __name__ == '__main__': |
||||
logging.basicConfig() |
||||
unittest.main(verbosity=2) |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,27 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/any.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg.h" |
||||
#include "google/protobuf/any.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout_field google_protobuf_Any__fields[2] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 9, 1}, |
||||
{2, UPB_SIZE(8, 16), 0, 0, 12, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Any_msginit = { |
||||
NULL, |
||||
&google_protobuf_Any__fields[0], |
||||
UPB_SIZE(16, 32), 2, false, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
@ -0,0 +1,59 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/any.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ |
||||
#define GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ |
||||
|
||||
#include "upb/generated_util.h" |
||||
|
||||
#include "upb/msg.h" |
||||
|
||||
#include "upb/decode.h" |
||||
#include "upb/encode.h" |
||||
#include "upb/port_def.inc" |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct google_protobuf_Any; |
||||
typedef struct google_protobuf_Any google_protobuf_Any; |
||||
extern const upb_msglayout google_protobuf_Any_msginit; |
||||
|
||||
/* Enums */ |
||||
|
||||
/* google.protobuf.Any */ |
||||
|
||||
UPB_INLINE google_protobuf_Any *google_protobuf_Any_new(upb_arena *arena) { |
||||
return (google_protobuf_Any *)upb_msg_new(&google_protobuf_Any_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Any *google_protobuf_Any_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Any *ret = google_protobuf_Any_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Any_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Any_serialize(const google_protobuf_Any *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Any_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE upb_strview google_protobuf_Any_type_url(const google_protobuf_Any *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } |
||||
UPB_INLINE upb_strview google_protobuf_Any_value(const google_protobuf_Any *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)); } |
||||
|
||||
UPB_INLINE void google_protobuf_Any_set_type_url(google_protobuf_Any *msg, upb_strview value) { |
||||
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
UPB_INLINE void google_protobuf_Any_set_value(google_protobuf_Any *msg, upb_strview value) { |
||||
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(8, 16)) = value; |
||||
} |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* GOOGLE_PROTOBUF_ANY_PROTO_UPB_H_ */ |
@ -0,0 +1,485 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/descriptor.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg.h" |
||||
#include "google/protobuf/descriptor.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout *const google_protobuf_FileDescriptorSet_submsgs[1] = { |
||||
&google_protobuf_FileDescriptorProto_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_FileDescriptorSet__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_FileDescriptorSet_msginit = { |
||||
&google_protobuf_FileDescriptorSet_submsgs[0], |
||||
&google_protobuf_FileDescriptorSet__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_FileDescriptorProto_submsgs[6] = { |
||||
&google_protobuf_DescriptorProto_msginit, |
||||
&google_protobuf_EnumDescriptorProto_msginit, |
||||
&google_protobuf_FieldDescriptorProto_msginit, |
||||
&google_protobuf_FileOptions_msginit, |
||||
&google_protobuf_ServiceDescriptorProto_msginit, |
||||
&google_protobuf_SourceCodeInfo_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_FileDescriptorProto__fields[12] = { |
||||
{1, UPB_SIZE(4, 8), 1, 0, 9, 1}, |
||||
{2, UPB_SIZE(12, 24), 2, 0, 9, 1}, |
||||
{3, UPB_SIZE(36, 72), 0, 0, 9, 3}, |
||||
{4, UPB_SIZE(40, 80), 0, 0, 11, 3}, |
||||
{5, UPB_SIZE(44, 88), 0, 1, 11, 3}, |
||||
{6, UPB_SIZE(48, 96), 0, 4, 11, 3}, |
||||
{7, UPB_SIZE(52, 104), 0, 2, 11, 3}, |
||||
{8, UPB_SIZE(28, 56), 4, 3, 11, 1}, |
||||
{9, UPB_SIZE(32, 64), 5, 5, 11, 1}, |
||||
{10, UPB_SIZE(56, 112), 0, 0, 5, 3}, |
||||
{11, UPB_SIZE(60, 120), 0, 0, 5, 3}, |
||||
{12, UPB_SIZE(20, 40), 3, 0, 9, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_FileDescriptorProto_msginit = { |
||||
&google_protobuf_FileDescriptorProto_submsgs[0], |
||||
&google_protobuf_FileDescriptorProto__fields[0], |
||||
UPB_SIZE(64, 128), 12, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_DescriptorProto_submsgs[8] = { |
||||
&google_protobuf_DescriptorProto_msginit, |
||||
&google_protobuf_DescriptorProto_ExtensionRange_msginit, |
||||
&google_protobuf_DescriptorProto_ReservedRange_msginit, |
||||
&google_protobuf_EnumDescriptorProto_msginit, |
||||
&google_protobuf_FieldDescriptorProto_msginit, |
||||
&google_protobuf_MessageOptions_msginit, |
||||
&google_protobuf_OneofDescriptorProto_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_DescriptorProto__fields[10] = { |
||||
{1, UPB_SIZE(4, 8), 1, 0, 9, 1}, |
||||
{2, UPB_SIZE(16, 32), 0, 4, 11, 3}, |
||||
{3, UPB_SIZE(20, 40), 0, 0, 11, 3}, |
||||
{4, UPB_SIZE(24, 48), 0, 3, 11, 3}, |
||||
{5, UPB_SIZE(28, 56), 0, 1, 11, 3}, |
||||
{6, UPB_SIZE(32, 64), 0, 4, 11, 3}, |
||||
{7, UPB_SIZE(12, 24), 2, 5, 11, 1}, |
||||
{8, UPB_SIZE(36, 72), 0, 6, 11, 3}, |
||||
{9, UPB_SIZE(40, 80), 0, 2, 11, 3}, |
||||
{10, UPB_SIZE(44, 88), 0, 0, 9, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_DescriptorProto_msginit = { |
||||
&google_protobuf_DescriptorProto_submsgs[0], |
||||
&google_protobuf_DescriptorProto__fields[0], |
||||
UPB_SIZE(48, 96), 10, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_DescriptorProto_ExtensionRange_submsgs[1] = { |
||||
&google_protobuf_ExtensionRangeOptions_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_DescriptorProto_ExtensionRange__fields[3] = { |
||||
{1, UPB_SIZE(4, 4), 1, 0, 5, 1}, |
||||
{2, UPB_SIZE(8, 8), 2, 0, 5, 1}, |
||||
{3, UPB_SIZE(12, 16), 3, 0, 11, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_DescriptorProto_ExtensionRange_msginit = { |
||||
&google_protobuf_DescriptorProto_ExtensionRange_submsgs[0], |
||||
&google_protobuf_DescriptorProto_ExtensionRange__fields[0], |
||||
UPB_SIZE(16, 24), 3, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_DescriptorProto_ReservedRange__fields[2] = { |
||||
{1, UPB_SIZE(4, 4), 1, 0, 5, 1}, |
||||
{2, UPB_SIZE(8, 8), 2, 0, 5, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_DescriptorProto_ReservedRange_msginit = { |
||||
NULL, |
||||
&google_protobuf_DescriptorProto_ReservedRange__fields[0], |
||||
UPB_SIZE(12, 12), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_ExtensionRangeOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_ExtensionRangeOptions__fields[1] = { |
||||
{999, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_ExtensionRangeOptions_msginit = { |
||||
&google_protobuf_ExtensionRangeOptions_submsgs[0], |
||||
&google_protobuf_ExtensionRangeOptions__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_FieldDescriptorProto_submsgs[1] = { |
||||
&google_protobuf_FieldOptions_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_FieldDescriptorProto__fields[10] = { |
||||
{1, UPB_SIZE(32, 32), 5, 0, 9, 1}, |
||||
{2, UPB_SIZE(40, 48), 6, 0, 9, 1}, |
||||
{3, UPB_SIZE(24, 24), 3, 0, 5, 1}, |
||||
{4, UPB_SIZE(8, 8), 1, 0, 14, 1}, |
||||
{5, UPB_SIZE(16, 16), 2, 0, 14, 1}, |
||||
{6, UPB_SIZE(48, 64), 7, 0, 9, 1}, |
||||
{7, UPB_SIZE(56, 80), 8, 0, 9, 1}, |
||||
{8, UPB_SIZE(72, 112), 10, 0, 11, 1}, |
||||
{9, UPB_SIZE(28, 28), 4, 0, 5, 1}, |
||||
{10, UPB_SIZE(64, 96), 9, 0, 9, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_FieldDescriptorProto_msginit = { |
||||
&google_protobuf_FieldDescriptorProto_submsgs[0], |
||||
&google_protobuf_FieldDescriptorProto__fields[0], |
||||
UPB_SIZE(80, 128), 10, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_OneofDescriptorProto_submsgs[1] = { |
||||
&google_protobuf_OneofOptions_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_OneofDescriptorProto__fields[2] = { |
||||
{1, UPB_SIZE(4, 8), 1, 0, 9, 1}, |
||||
{2, UPB_SIZE(12, 24), 2, 0, 11, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_OneofDescriptorProto_msginit = { |
||||
&google_protobuf_OneofDescriptorProto_submsgs[0], |
||||
&google_protobuf_OneofDescriptorProto__fields[0], |
||||
UPB_SIZE(16, 32), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_EnumDescriptorProto_submsgs[3] = { |
||||
&google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit, |
||||
&google_protobuf_EnumOptions_msginit, |
||||
&google_protobuf_EnumValueDescriptorProto_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_EnumDescriptorProto__fields[5] = { |
||||
{1, UPB_SIZE(4, 8), 1, 0, 9, 1}, |
||||
{2, UPB_SIZE(16, 32), 0, 2, 11, 3}, |
||||
{3, UPB_SIZE(12, 24), 2, 1, 11, 1}, |
||||
{4, UPB_SIZE(20, 40), 0, 0, 11, 3}, |
||||
{5, UPB_SIZE(24, 48), 0, 0, 9, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_EnumDescriptorProto_msginit = { |
||||
&google_protobuf_EnumDescriptorProto_submsgs[0], |
||||
&google_protobuf_EnumDescriptorProto__fields[0], |
||||
UPB_SIZE(32, 64), 5, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[2] = { |
||||
{1, UPB_SIZE(4, 4), 1, 0, 5, 1}, |
||||
{2, UPB_SIZE(8, 8), 2, 0, 5, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_EnumDescriptorProto_EnumReservedRange_msginit = { |
||||
NULL, |
||||
&google_protobuf_EnumDescriptorProto_EnumReservedRange__fields[0], |
||||
UPB_SIZE(12, 12), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_EnumValueDescriptorProto_submsgs[1] = { |
||||
&google_protobuf_EnumValueOptions_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_EnumValueDescriptorProto__fields[3] = { |
||||
{1, UPB_SIZE(8, 8), 2, 0, 9, 1}, |
||||
{2, UPB_SIZE(4, 4), 1, 0, 5, 1}, |
||||
{3, UPB_SIZE(16, 24), 3, 0, 11, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_EnumValueDescriptorProto_msginit = { |
||||
&google_protobuf_EnumValueDescriptorProto_submsgs[0], |
||||
&google_protobuf_EnumValueDescriptorProto__fields[0], |
||||
UPB_SIZE(24, 32), 3, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_ServiceDescriptorProto_submsgs[2] = { |
||||
&google_protobuf_MethodDescriptorProto_msginit, |
||||
&google_protobuf_ServiceOptions_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_ServiceDescriptorProto__fields[3] = { |
||||
{1, UPB_SIZE(4, 8), 1, 0, 9, 1}, |
||||
{2, UPB_SIZE(16, 32), 0, 0, 11, 3}, |
||||
{3, UPB_SIZE(12, 24), 2, 1, 11, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_ServiceDescriptorProto_msginit = { |
||||
&google_protobuf_ServiceDescriptorProto_submsgs[0], |
||||
&google_protobuf_ServiceDescriptorProto__fields[0], |
||||
UPB_SIZE(24, 48), 3, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_MethodDescriptorProto_submsgs[1] = { |
||||
&google_protobuf_MethodOptions_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_MethodDescriptorProto__fields[6] = { |
||||
{1, UPB_SIZE(4, 8), 3, 0, 9, 1}, |
||||
{2, UPB_SIZE(12, 24), 4, 0, 9, 1}, |
||||
{3, UPB_SIZE(20, 40), 5, 0, 9, 1}, |
||||
{4, UPB_SIZE(28, 56), 6, 0, 11, 1}, |
||||
{5, UPB_SIZE(1, 1), 1, 0, 8, 1}, |
||||
{6, UPB_SIZE(2, 2), 2, 0, 8, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_MethodDescriptorProto_msginit = { |
||||
&google_protobuf_MethodDescriptorProto_submsgs[0], |
||||
&google_protobuf_MethodDescriptorProto__fields[0], |
||||
UPB_SIZE(32, 64), 6, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_FileOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_FileOptions__fields[21] = { |
||||
{1, UPB_SIZE(28, 32), 11, 0, 9, 1}, |
||||
{8, UPB_SIZE(36, 48), 12, 0, 9, 1}, |
||||
{9, UPB_SIZE(8, 8), 1, 0, 14, 1}, |
||||
{10, UPB_SIZE(16, 16), 2, 0, 8, 1}, |
||||
{11, UPB_SIZE(44, 64), 13, 0, 9, 1}, |
||||
{16, UPB_SIZE(17, 17), 3, 0, 8, 1}, |
||||
{17, UPB_SIZE(18, 18), 4, 0, 8, 1}, |
||||
{18, UPB_SIZE(19, 19), 5, 0, 8, 1}, |
||||
{20, UPB_SIZE(20, 20), 6, 0, 8, 1}, |
||||
{23, UPB_SIZE(21, 21), 7, 0, 8, 1}, |
||||
{27, UPB_SIZE(22, 22), 8, 0, 8, 1}, |
||||
{31, UPB_SIZE(23, 23), 9, 0, 8, 1}, |
||||
{36, UPB_SIZE(52, 80), 14, 0, 9, 1}, |
||||
{37, UPB_SIZE(60, 96), 15, 0, 9, 1}, |
||||
{39, UPB_SIZE(68, 112), 16, 0, 9, 1}, |
||||
{40, UPB_SIZE(76, 128), 17, 0, 9, 1}, |
||||
{41, UPB_SIZE(84, 144), 18, 0, 9, 1}, |
||||
{42, UPB_SIZE(24, 24), 10, 0, 8, 1}, |
||||
{44, UPB_SIZE(92, 160), 19, 0, 9, 1}, |
||||
{45, UPB_SIZE(100, 176), 20, 0, 9, 1}, |
||||
{999, UPB_SIZE(108, 192), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_FileOptions_msginit = { |
||||
&google_protobuf_FileOptions_submsgs[0], |
||||
&google_protobuf_FileOptions__fields[0], |
||||
UPB_SIZE(112, 208), 21, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_MessageOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_MessageOptions__fields[5] = { |
||||
{1, UPB_SIZE(1, 1), 1, 0, 8, 1}, |
||||
{2, UPB_SIZE(2, 2), 2, 0, 8, 1}, |
||||
{3, UPB_SIZE(3, 3), 3, 0, 8, 1}, |
||||
{7, UPB_SIZE(4, 4), 4, 0, 8, 1}, |
||||
{999, UPB_SIZE(8, 8), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_MessageOptions_msginit = { |
||||
&google_protobuf_MessageOptions_submsgs[0], |
||||
&google_protobuf_MessageOptions__fields[0], |
||||
UPB_SIZE(12, 16), 5, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_FieldOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_FieldOptions__fields[7] = { |
||||
{1, UPB_SIZE(8, 8), 1, 0, 14, 1}, |
||||
{2, UPB_SIZE(24, 24), 3, 0, 8, 1}, |
||||
{3, UPB_SIZE(25, 25), 4, 0, 8, 1}, |
||||
{5, UPB_SIZE(26, 26), 5, 0, 8, 1}, |
||||
{6, UPB_SIZE(16, 16), 2, 0, 14, 1}, |
||||
{10, UPB_SIZE(27, 27), 6, 0, 8, 1}, |
||||
{999, UPB_SIZE(28, 32), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_FieldOptions_msginit = { |
||||
&google_protobuf_FieldOptions_submsgs[0], |
||||
&google_protobuf_FieldOptions__fields[0], |
||||
UPB_SIZE(32, 40), 7, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_OneofOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_OneofOptions__fields[1] = { |
||||
{999, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_OneofOptions_msginit = { |
||||
&google_protobuf_OneofOptions_submsgs[0], |
||||
&google_protobuf_OneofOptions__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_EnumOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_EnumOptions__fields[3] = { |
||||
{2, UPB_SIZE(1, 1), 1, 0, 8, 1}, |
||||
{3, UPB_SIZE(2, 2), 2, 0, 8, 1}, |
||||
{999, UPB_SIZE(4, 8), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_EnumOptions_msginit = { |
||||
&google_protobuf_EnumOptions_submsgs[0], |
||||
&google_protobuf_EnumOptions__fields[0], |
||||
UPB_SIZE(8, 16), 3, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_EnumValueOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_EnumValueOptions__fields[2] = { |
||||
{1, UPB_SIZE(1, 1), 1, 0, 8, 1}, |
||||
{999, UPB_SIZE(4, 8), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_EnumValueOptions_msginit = { |
||||
&google_protobuf_EnumValueOptions_submsgs[0], |
||||
&google_protobuf_EnumValueOptions__fields[0], |
||||
UPB_SIZE(8, 16), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_ServiceOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_ServiceOptions__fields[2] = { |
||||
{33, UPB_SIZE(1, 1), 1, 0, 8, 1}, |
||||
{999, UPB_SIZE(4, 8), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_ServiceOptions_msginit = { |
||||
&google_protobuf_ServiceOptions_submsgs[0], |
||||
&google_protobuf_ServiceOptions__fields[0], |
||||
UPB_SIZE(8, 16), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_MethodOptions_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_MethodOptions__fields[3] = { |
||||
{33, UPB_SIZE(16, 16), 2, 0, 8, 1}, |
||||
{34, UPB_SIZE(8, 8), 1, 0, 14, 1}, |
||||
{999, UPB_SIZE(20, 24), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_MethodOptions_msginit = { |
||||
&google_protobuf_MethodOptions_submsgs[0], |
||||
&google_protobuf_MethodOptions__fields[0], |
||||
UPB_SIZE(24, 32), 3, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_UninterpretedOption_submsgs[1] = { |
||||
&google_protobuf_UninterpretedOption_NamePart_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_UninterpretedOption__fields[7] = { |
||||
{2, UPB_SIZE(56, 80), 0, 0, 11, 3}, |
||||
{3, UPB_SIZE(32, 32), 4, 0, 9, 1}, |
||||
{4, UPB_SIZE(8, 8), 1, 0, 4, 1}, |
||||
{5, UPB_SIZE(16, 16), 2, 0, 3, 1}, |
||||
{6, UPB_SIZE(24, 24), 3, 0, 1, 1}, |
||||
{7, UPB_SIZE(40, 48), 5, 0, 12, 1}, |
||||
{8, UPB_SIZE(48, 64), 6, 0, 9, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_UninterpretedOption_msginit = { |
||||
&google_protobuf_UninterpretedOption_submsgs[0], |
||||
&google_protobuf_UninterpretedOption__fields[0], |
||||
UPB_SIZE(64, 96), 7, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_UninterpretedOption_NamePart__fields[2] = { |
||||
{1, UPB_SIZE(4, 8), 2, 0, 9, 2}, |
||||
{2, UPB_SIZE(1, 1), 1, 0, 8, 2}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_UninterpretedOption_NamePart_msginit = { |
||||
NULL, |
||||
&google_protobuf_UninterpretedOption_NamePart__fields[0], |
||||
UPB_SIZE(16, 32), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_SourceCodeInfo_submsgs[1] = { |
||||
&google_protobuf_SourceCodeInfo_Location_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_SourceCodeInfo__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_SourceCodeInfo_msginit = { |
||||
&google_protobuf_SourceCodeInfo_submsgs[0], |
||||
&google_protobuf_SourceCodeInfo__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_SourceCodeInfo_Location__fields[5] = { |
||||
{1, UPB_SIZE(20, 40), 0, 0, 5, 3}, |
||||
{2, UPB_SIZE(24, 48), 0, 0, 5, 3}, |
||||
{3, UPB_SIZE(4, 8), 1, 0, 9, 1}, |
||||
{4, UPB_SIZE(12, 24), 2, 0, 9, 1}, |
||||
{6, UPB_SIZE(28, 56), 0, 0, 9, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_SourceCodeInfo_Location_msginit = { |
||||
NULL, |
||||
&google_protobuf_SourceCodeInfo_Location__fields[0], |
||||
UPB_SIZE(32, 64), 5, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_GeneratedCodeInfo_submsgs[1] = { |
||||
&google_protobuf_GeneratedCodeInfo_Annotation_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_GeneratedCodeInfo_msginit = { |
||||
&google_protobuf_GeneratedCodeInfo_submsgs[0], |
||||
&google_protobuf_GeneratedCodeInfo__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_GeneratedCodeInfo_Annotation__fields[4] = { |
||||
{1, UPB_SIZE(20, 32), 0, 0, 5, 3}, |
||||
{2, UPB_SIZE(12, 16), 3, 0, 9, 1}, |
||||
{3, UPB_SIZE(4, 4), 1, 0, 5, 1}, |
||||
{4, UPB_SIZE(8, 8), 2, 0, 5, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_GeneratedCodeInfo_Annotation_msginit = { |
||||
NULL, |
||||
&google_protobuf_GeneratedCodeInfo_Annotation__fields[0], |
||||
UPB_SIZE(24, 48), 4, false, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,27 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/duration.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg.h" |
||||
#include "google/protobuf/duration.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout_field google_protobuf_Duration__fields[2] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 3, 1}, |
||||
{2, UPB_SIZE(8, 8), 0, 0, 5, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Duration_msginit = { |
||||
NULL, |
||||
&google_protobuf_Duration__fields[0], |
||||
UPB_SIZE(16, 16), 2, false, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
@ -0,0 +1,59 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/duration.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ |
||||
#define GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ |
||||
|
||||
#include "upb/generated_util.h" |
||||
|
||||
#include "upb/msg.h" |
||||
|
||||
#include "upb/decode.h" |
||||
#include "upb/encode.h" |
||||
#include "upb/port_def.inc" |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct google_protobuf_Duration; |
||||
typedef struct google_protobuf_Duration google_protobuf_Duration; |
||||
extern const upb_msglayout google_protobuf_Duration_msginit; |
||||
|
||||
/* Enums */ |
||||
|
||||
/* google.protobuf.Duration */ |
||||
|
||||
UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_new(upb_arena *arena) { |
||||
return (google_protobuf_Duration *)upb_msg_new(&google_protobuf_Duration_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Duration *google_protobuf_Duration_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Duration *ret = google_protobuf_Duration_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Duration_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Duration_serialize(const google_protobuf_Duration *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Duration_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE int64_t google_protobuf_Duration_seconds(const google_protobuf_Duration *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } |
||||
UPB_INLINE int32_t google_protobuf_Duration_nanos(const google_protobuf_Duration *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } |
||||
|
||||
UPB_INLINE void google_protobuf_Duration_set_seconds(google_protobuf_Duration *msg, int64_t value) { |
||||
UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
UPB_INLINE void google_protobuf_Duration_set_nanos(google_protobuf_Duration *msg, int32_t value) { |
||||
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; |
||||
} |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* GOOGLE_PROTOBUF_DURATION_PROTO_UPB_H_ */ |
@ -0,0 +1,79 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/struct.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg.h" |
||||
#include "google/protobuf/struct.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout *const google_protobuf_Struct_submsgs[1] = { |
||||
&google_protobuf_Struct_FieldsEntry_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_Struct__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Struct_msginit = { |
||||
&google_protobuf_Struct_submsgs[0], |
||||
&google_protobuf_Struct__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_Struct_FieldsEntry_submsgs[1] = { |
||||
&google_protobuf_Value_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_Struct_FieldsEntry__fields[2] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 9, 1}, |
||||
{2, UPB_SIZE(8, 16), 0, 0, 11, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit = { |
||||
&google_protobuf_Struct_FieldsEntry_submsgs[0], |
||||
&google_protobuf_Struct_FieldsEntry__fields[0], |
||||
UPB_SIZE(16, 32), 2, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_Value_submsgs[2] = { |
||||
&google_protobuf_ListValue_msginit, |
||||
&google_protobuf_Struct_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_Value__fields[6] = { |
||||
{1, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 14, 1}, |
||||
{2, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 1, 1}, |
||||
{3, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 9, 1}, |
||||
{4, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 8, 1}, |
||||
{5, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 1, 11, 1}, |
||||
{6, UPB_SIZE(0, 0), UPB_SIZE(-9, -17), 0, 11, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Value_msginit = { |
||||
&google_protobuf_Value_submsgs[0], |
||||
&google_protobuf_Value__fields[0], |
||||
UPB_SIZE(16, 32), 6, false, |
||||
}; |
||||
|
||||
static const upb_msglayout *const google_protobuf_ListValue_submsgs[1] = { |
||||
&google_protobuf_Value_msginit, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_ListValue__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 11, 3}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_ListValue_msginit = { |
||||
&google_protobuf_ListValue_submsgs[0], |
||||
&google_protobuf_ListValue__fields[0], |
||||
UPB_SIZE(4, 8), 1, false, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
@ -0,0 +1,216 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/struct.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ |
||||
#define GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ |
||||
|
||||
#include "upb/generated_util.h" |
||||
|
||||
#include "upb/msg.h" |
||||
|
||||
#include "upb/decode.h" |
||||
#include "upb/encode.h" |
||||
#include "upb/port_def.inc" |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct google_protobuf_Struct; |
||||
struct google_protobuf_Struct_FieldsEntry; |
||||
struct google_protobuf_Value; |
||||
struct google_protobuf_ListValue; |
||||
typedef struct google_protobuf_Struct google_protobuf_Struct; |
||||
typedef struct google_protobuf_Struct_FieldsEntry google_protobuf_Struct_FieldsEntry; |
||||
typedef struct google_protobuf_Value google_protobuf_Value; |
||||
typedef struct google_protobuf_ListValue google_protobuf_ListValue; |
||||
extern const upb_msglayout google_protobuf_Struct_msginit; |
||||
extern const upb_msglayout google_protobuf_Struct_FieldsEntry_msginit; |
||||
extern const upb_msglayout google_protobuf_Value_msginit; |
||||
extern const upb_msglayout google_protobuf_ListValue_msginit; |
||||
|
||||
/* Enums */ |
||||
|
||||
typedef enum { |
||||
google_protobuf_NULL_VALUE = 0 |
||||
} google_protobuf_NullValue; |
||||
|
||||
/* google.protobuf.Struct */ |
||||
|
||||
UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_new(upb_arena *arena) { |
||||
return (google_protobuf_Struct *)upb_msg_new(&google_protobuf_Struct_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Struct *google_protobuf_Struct_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Struct *ret = google_protobuf_Struct_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Struct_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Struct_serialize(const google_protobuf_Struct *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Struct_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE const google_protobuf_Struct_FieldsEntry* const* google_protobuf_Struct_fields(const google_protobuf_Struct *msg, size_t *len) { return (const google_protobuf_Struct_FieldsEntry* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } |
||||
|
||||
UPB_INLINE google_protobuf_Struct_FieldsEntry** google_protobuf_Struct_mutable_fields(google_protobuf_Struct *msg, size_t *len) { |
||||
return (google_protobuf_Struct_FieldsEntry**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); |
||||
} |
||||
UPB_INLINE google_protobuf_Struct_FieldsEntry** google_protobuf_Struct_resize_fields(google_protobuf_Struct *msg, size_t len, upb_arena *arena) { |
||||
return (google_protobuf_Struct_FieldsEntry**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); |
||||
} |
||||
UPB_INLINE struct google_protobuf_Struct_FieldsEntry* google_protobuf_Struct_add_fields(google_protobuf_Struct *msg, upb_arena *arena) { |
||||
struct google_protobuf_Struct_FieldsEntry* sub = (struct google_protobuf_Struct_FieldsEntry*)upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); |
||||
bool ok = _upb_array_append_accessor( |
||||
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); |
||||
if (!ok) return NULL; |
||||
return sub; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.Struct.FieldsEntry */ |
||||
|
||||
UPB_INLINE google_protobuf_Struct_FieldsEntry *google_protobuf_Struct_FieldsEntry_new(upb_arena *arena) { |
||||
return (google_protobuf_Struct_FieldsEntry *)upb_msg_new(&google_protobuf_Struct_FieldsEntry_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Struct_FieldsEntry *google_protobuf_Struct_FieldsEntry_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Struct_FieldsEntry *ret = google_protobuf_Struct_FieldsEntry_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Struct_FieldsEntry_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Struct_FieldsEntry_serialize(const google_protobuf_Struct_FieldsEntry *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Struct_FieldsEntry_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE upb_strview google_protobuf_Struct_FieldsEntry_key(const google_protobuf_Struct_FieldsEntry *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } |
||||
UPB_INLINE const google_protobuf_Value* google_protobuf_Struct_FieldsEntry_value(const google_protobuf_Struct_FieldsEntry *msg) { return UPB_FIELD_AT(msg, const google_protobuf_Value*, UPB_SIZE(8, 16)); } |
||||
|
||||
UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_key(google_protobuf_Struct_FieldsEntry *msg, upb_strview value) { |
||||
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
UPB_INLINE void google_protobuf_Struct_FieldsEntry_set_value(google_protobuf_Struct_FieldsEntry *msg, google_protobuf_Value* value) { |
||||
UPB_FIELD_AT(msg, google_protobuf_Value*, UPB_SIZE(8, 16)) = value; |
||||
} |
||||
UPB_INLINE struct google_protobuf_Value* google_protobuf_Struct_FieldsEntry_mutable_value(google_protobuf_Struct_FieldsEntry *msg, upb_arena *arena) { |
||||
struct google_protobuf_Value* sub = (struct google_protobuf_Value*)google_protobuf_Struct_FieldsEntry_value(msg); |
||||
if (sub == NULL) { |
||||
sub = (struct google_protobuf_Value*)upb_msg_new(&google_protobuf_Value_msginit, arena); |
||||
if (!sub) return NULL; |
||||
google_protobuf_Struct_FieldsEntry_set_value(msg, sub); |
||||
} |
||||
return sub; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.Value */ |
||||
|
||||
UPB_INLINE google_protobuf_Value *google_protobuf_Value_new(upb_arena *arena) { |
||||
return (google_protobuf_Value *)upb_msg_new(&google_protobuf_Value_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Value *google_protobuf_Value_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Value *ret = google_protobuf_Value_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Value_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Value_serialize(const google_protobuf_Value *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Value_msginit, arena, len); |
||||
} |
||||
|
||||
typedef enum { |
||||
google_protobuf_Value_kind_null_value = 1, |
||||
google_protobuf_Value_kind_number_value = 2, |
||||
google_protobuf_Value_kind_string_value = 3, |
||||
google_protobuf_Value_kind_bool_value = 4, |
||||
google_protobuf_Value_kind_struct_value = 5, |
||||
google_protobuf_Value_kind_list_value = 6, |
||||
google_protobuf_Value_kind_NOT_SET = 0, |
||||
} google_protobuf_Value_kind_oneofcases; |
||||
UPB_INLINE google_protobuf_Value_kind_oneofcases google_protobuf_Value_kind_case(const google_protobuf_Value* msg) { return UPB_FIELD_AT(msg, int, UPB_SIZE(8, 16)); } |
||||
|
||||
UPB_INLINE bool google_protobuf_Value_has_null_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 1); } |
||||
UPB_INLINE google_protobuf_NullValue google_protobuf_Value_null_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 1, google_protobuf_NULL_VALUE); } |
||||
UPB_INLINE bool google_protobuf_Value_has_number_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 2); } |
||||
UPB_INLINE double google_protobuf_Value_number_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, double, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 2, 0); } |
||||
UPB_INLINE bool google_protobuf_Value_has_string_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 3); } |
||||
UPB_INLINE upb_strview google_protobuf_Value_string_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 3, upb_strview_make("", strlen(""))); } |
||||
UPB_INLINE bool google_protobuf_Value_has_bool_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 4); } |
||||
UPB_INLINE bool google_protobuf_Value_bool_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, bool, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 4, false); } |
||||
UPB_INLINE bool google_protobuf_Value_has_struct_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 5); } |
||||
UPB_INLINE const google_protobuf_Struct* google_protobuf_Value_struct_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_Struct*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 5, NULL); } |
||||
UPB_INLINE bool google_protobuf_Value_has_list_value(const google_protobuf_Value *msg) { return _upb_has_oneof_field(msg, UPB_SIZE(8, 16), 6); } |
||||
UPB_INLINE const google_protobuf_ListValue* google_protobuf_Value_list_value(const google_protobuf_Value *msg) { return UPB_READ_ONEOF(msg, const google_protobuf_ListValue*, UPB_SIZE(0, 0), UPB_SIZE(8, 16), 6, NULL); } |
||||
|
||||
UPB_INLINE void google_protobuf_Value_set_null_value(google_protobuf_Value *msg, google_protobuf_NullValue value) { |
||||
UPB_WRITE_ONEOF(msg, google_protobuf_NullValue, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 1); |
||||
} |
||||
UPB_INLINE void google_protobuf_Value_set_number_value(google_protobuf_Value *msg, double value) { |
||||
UPB_WRITE_ONEOF(msg, double, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 2); |
||||
} |
||||
UPB_INLINE void google_protobuf_Value_set_string_value(google_protobuf_Value *msg, upb_strview value) { |
||||
UPB_WRITE_ONEOF(msg, upb_strview, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 3); |
||||
} |
||||
UPB_INLINE void google_protobuf_Value_set_bool_value(google_protobuf_Value *msg, bool value) { |
||||
UPB_WRITE_ONEOF(msg, bool, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 4); |
||||
} |
||||
UPB_INLINE void google_protobuf_Value_set_struct_value(google_protobuf_Value *msg, google_protobuf_Struct* value) { |
||||
UPB_WRITE_ONEOF(msg, google_protobuf_Struct*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 5); |
||||
} |
||||
UPB_INLINE struct google_protobuf_Struct* google_protobuf_Value_mutable_struct_value(google_protobuf_Value *msg, upb_arena *arena) { |
||||
struct google_protobuf_Struct* sub = (struct google_protobuf_Struct*)google_protobuf_Value_struct_value(msg); |
||||
if (sub == NULL) { |
||||
sub = (struct google_protobuf_Struct*)upb_msg_new(&google_protobuf_Struct_msginit, arena); |
||||
if (!sub) return NULL; |
||||
google_protobuf_Value_set_struct_value(msg, sub); |
||||
} |
||||
return sub; |
||||
} |
||||
UPB_INLINE void google_protobuf_Value_set_list_value(google_protobuf_Value *msg, google_protobuf_ListValue* value) { |
||||
UPB_WRITE_ONEOF(msg, google_protobuf_ListValue*, UPB_SIZE(0, 0), value, UPB_SIZE(8, 16), 6); |
||||
} |
||||
UPB_INLINE struct google_protobuf_ListValue* google_protobuf_Value_mutable_list_value(google_protobuf_Value *msg, upb_arena *arena) { |
||||
struct google_protobuf_ListValue* sub = (struct google_protobuf_ListValue*)google_protobuf_Value_list_value(msg); |
||||
if (sub == NULL) { |
||||
sub = (struct google_protobuf_ListValue*)upb_msg_new(&google_protobuf_ListValue_msginit, arena); |
||||
if (!sub) return NULL; |
||||
google_protobuf_Value_set_list_value(msg, sub); |
||||
} |
||||
return sub; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.ListValue */ |
||||
|
||||
UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_new(upb_arena *arena) { |
||||
return (google_protobuf_ListValue *)upb_msg_new(&google_protobuf_ListValue_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_ListValue *google_protobuf_ListValue_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_ListValue *ret = google_protobuf_ListValue_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_ListValue_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_ListValue_serialize(const google_protobuf_ListValue *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_ListValue_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE const google_protobuf_Value* const* google_protobuf_ListValue_values(const google_protobuf_ListValue *msg, size_t *len) { return (const google_protobuf_Value* const*)_upb_array_accessor(msg, UPB_SIZE(0, 0), len); } |
||||
|
||||
UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_mutable_values(google_protobuf_ListValue *msg, size_t *len) { |
||||
return (google_protobuf_Value**)_upb_array_mutable_accessor(msg, UPB_SIZE(0, 0), len); |
||||
} |
||||
UPB_INLINE google_protobuf_Value** google_protobuf_ListValue_resize_values(google_protobuf_ListValue *msg, size_t len, upb_arena *arena) { |
||||
return (google_protobuf_Value**)_upb_array_resize_accessor(msg, UPB_SIZE(0, 0), len, UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, arena); |
||||
} |
||||
UPB_INLINE struct google_protobuf_Value* google_protobuf_ListValue_add_values(google_protobuf_ListValue *msg, upb_arena *arena) { |
||||
struct google_protobuf_Value* sub = (struct google_protobuf_Value*)upb_msg_new(&google_protobuf_Value_msginit, arena); |
||||
bool ok = _upb_array_append_accessor( |
||||
msg, UPB_SIZE(0, 0), UPB_SIZE(4, 8), UPB_TYPE_MESSAGE, &sub, arena); |
||||
if (!ok) return NULL; |
||||
return sub; |
||||
} |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* GOOGLE_PROTOBUF_STRUCT_PROTO_UPB_H_ */ |
@ -0,0 +1,27 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/timestamp.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg.h" |
||||
#include "google/protobuf/timestamp.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout_field google_protobuf_Timestamp__fields[2] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 3, 1}, |
||||
{2, UPB_SIZE(8, 8), 0, 0, 5, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Timestamp_msginit = { |
||||
NULL, |
||||
&google_protobuf_Timestamp__fields[0], |
||||
UPB_SIZE(16, 16), 2, false, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
@ -0,0 +1,59 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/timestamp.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ |
||||
#define GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ |
||||
|
||||
#include "upb/generated_util.h" |
||||
|
||||
#include "upb/msg.h" |
||||
|
||||
#include "upb/decode.h" |
||||
#include "upb/encode.h" |
||||
#include "upb/port_def.inc" |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct google_protobuf_Timestamp; |
||||
typedef struct google_protobuf_Timestamp google_protobuf_Timestamp; |
||||
extern const upb_msglayout google_protobuf_Timestamp_msginit; |
||||
|
||||
/* Enums */ |
||||
|
||||
/* google.protobuf.Timestamp */ |
||||
|
||||
UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_new(upb_arena *arena) { |
||||
return (google_protobuf_Timestamp *)upb_msg_new(&google_protobuf_Timestamp_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Timestamp *google_protobuf_Timestamp_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Timestamp *ret = google_protobuf_Timestamp_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Timestamp_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Timestamp_serialize(const google_protobuf_Timestamp *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Timestamp_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE int64_t google_protobuf_Timestamp_seconds(const google_protobuf_Timestamp *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } |
||||
UPB_INLINE int32_t google_protobuf_Timestamp_nanos(const google_protobuf_Timestamp *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)); } |
||||
|
||||
UPB_INLINE void google_protobuf_Timestamp_set_seconds(google_protobuf_Timestamp *msg, int64_t value) { |
||||
UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
UPB_INLINE void google_protobuf_Timestamp_set_nanos(google_protobuf_Timestamp *msg, int32_t value) { |
||||
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(8, 8)) = value; |
||||
} |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* GOOGLE_PROTOBUF_TIMESTAMP_PROTO_UPB_H_ */ |
@ -0,0 +1,106 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/wrappers.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#include <stddef.h> |
||||
#include "upb/msg.h" |
||||
#include "google/protobuf/wrappers.upb.h" |
||||
|
||||
#include "upb/port_def.inc" |
||||
|
||||
static const upb_msglayout_field google_protobuf_DoubleValue__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 1, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_DoubleValue_msginit = { |
||||
NULL, |
||||
&google_protobuf_DoubleValue__fields[0], |
||||
UPB_SIZE(8, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_FloatValue__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 2, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_FloatValue_msginit = { |
||||
NULL, |
||||
&google_protobuf_FloatValue__fields[0], |
||||
UPB_SIZE(4, 4), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_Int64Value__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 3, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Int64Value_msginit = { |
||||
NULL, |
||||
&google_protobuf_Int64Value__fields[0], |
||||
UPB_SIZE(8, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_UInt64Value__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 4, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_UInt64Value_msginit = { |
||||
NULL, |
||||
&google_protobuf_UInt64Value__fields[0], |
||||
UPB_SIZE(8, 8), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_Int32Value__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 5, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_Int32Value_msginit = { |
||||
NULL, |
||||
&google_protobuf_Int32Value__fields[0], |
||||
UPB_SIZE(4, 4), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_UInt32Value__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 13, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_UInt32Value_msginit = { |
||||
NULL, |
||||
&google_protobuf_UInt32Value__fields[0], |
||||
UPB_SIZE(4, 4), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_BoolValue__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 8, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_BoolValue_msginit = { |
||||
NULL, |
||||
&google_protobuf_BoolValue__fields[0], |
||||
UPB_SIZE(1, 1), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_StringValue__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 9, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_StringValue_msginit = { |
||||
NULL, |
||||
&google_protobuf_StringValue__fields[0], |
||||
UPB_SIZE(8, 16), 1, false, |
||||
}; |
||||
|
||||
static const upb_msglayout_field google_protobuf_BytesValue__fields[1] = { |
||||
{1, UPB_SIZE(0, 0), 0, 0, 12, 1}, |
||||
}; |
||||
|
||||
const upb_msglayout google_protobuf_BytesValue_msginit = { |
||||
NULL, |
||||
&google_protobuf_BytesValue__fields[0], |
||||
UPB_SIZE(8, 16), 1, false, |
||||
}; |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
@ -0,0 +1,239 @@ |
||||
/* This file was generated by upbc (the upb compiler) from the input
|
||||
* file: |
||||
* |
||||
* google/protobuf/wrappers.proto |
||||
* |
||||
* Do not edit -- your changes will be discarded when the file is |
||||
* regenerated. */ |
||||
|
||||
#ifndef GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ |
||||
#define GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ |
||||
|
||||
#include "upb/generated_util.h" |
||||
|
||||
#include "upb/msg.h" |
||||
|
||||
#include "upb/decode.h" |
||||
#include "upb/encode.h" |
||||
#include "upb/port_def.inc" |
||||
#ifdef __cplusplus |
||||
extern "C" { |
||||
#endif |
||||
|
||||
struct google_protobuf_DoubleValue; |
||||
struct google_protobuf_FloatValue; |
||||
struct google_protobuf_Int64Value; |
||||
struct google_protobuf_UInt64Value; |
||||
struct google_protobuf_Int32Value; |
||||
struct google_protobuf_UInt32Value; |
||||
struct google_protobuf_BoolValue; |
||||
struct google_protobuf_StringValue; |
||||
struct google_protobuf_BytesValue; |
||||
typedef struct google_protobuf_DoubleValue google_protobuf_DoubleValue; |
||||
typedef struct google_protobuf_FloatValue google_protobuf_FloatValue; |
||||
typedef struct google_protobuf_Int64Value google_protobuf_Int64Value; |
||||
typedef struct google_protobuf_UInt64Value google_protobuf_UInt64Value; |
||||
typedef struct google_protobuf_Int32Value google_protobuf_Int32Value; |
||||
typedef struct google_protobuf_UInt32Value google_protobuf_UInt32Value; |
||||
typedef struct google_protobuf_BoolValue google_protobuf_BoolValue; |
||||
typedef struct google_protobuf_StringValue google_protobuf_StringValue; |
||||
typedef struct google_protobuf_BytesValue google_protobuf_BytesValue; |
||||
extern const upb_msglayout google_protobuf_DoubleValue_msginit; |
||||
extern const upb_msglayout google_protobuf_FloatValue_msginit; |
||||
extern const upb_msglayout google_protobuf_Int64Value_msginit; |
||||
extern const upb_msglayout google_protobuf_UInt64Value_msginit; |
||||
extern const upb_msglayout google_protobuf_Int32Value_msginit; |
||||
extern const upb_msglayout google_protobuf_UInt32Value_msginit; |
||||
extern const upb_msglayout google_protobuf_BoolValue_msginit; |
||||
extern const upb_msglayout google_protobuf_StringValue_msginit; |
||||
extern const upb_msglayout google_protobuf_BytesValue_msginit; |
||||
|
||||
/* Enums */ |
||||
|
||||
/* google.protobuf.DoubleValue */ |
||||
|
||||
UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_new(upb_arena *arena) { |
||||
return (google_protobuf_DoubleValue *)upb_msg_new(&google_protobuf_DoubleValue_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_DoubleValue *google_protobuf_DoubleValue_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_DoubleValue *ret = google_protobuf_DoubleValue_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_DoubleValue_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_DoubleValue_serialize(const google_protobuf_DoubleValue *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_DoubleValue_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE double google_protobuf_DoubleValue_value(const google_protobuf_DoubleValue *msg) { return UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_DoubleValue_set_value(google_protobuf_DoubleValue *msg, double value) { |
||||
UPB_FIELD_AT(msg, double, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.FloatValue */ |
||||
|
||||
UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_new(upb_arena *arena) { |
||||
return (google_protobuf_FloatValue *)upb_msg_new(&google_protobuf_FloatValue_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_FloatValue *google_protobuf_FloatValue_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_FloatValue *ret = google_protobuf_FloatValue_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_FloatValue_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_FloatValue_serialize(const google_protobuf_FloatValue *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_FloatValue_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE float google_protobuf_FloatValue_value(const google_protobuf_FloatValue *msg) { return UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_FloatValue_set_value(google_protobuf_FloatValue *msg, float value) { |
||||
UPB_FIELD_AT(msg, float, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.Int64Value */ |
||||
|
||||
UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_new(upb_arena *arena) { |
||||
return (google_protobuf_Int64Value *)upb_msg_new(&google_protobuf_Int64Value_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Int64Value *google_protobuf_Int64Value_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Int64Value *ret = google_protobuf_Int64Value_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Int64Value_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Int64Value_serialize(const google_protobuf_Int64Value *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Int64Value_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE int64_t google_protobuf_Int64Value_value(const google_protobuf_Int64Value *msg) { return UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_Int64Value_set_value(google_protobuf_Int64Value *msg, int64_t value) { |
||||
UPB_FIELD_AT(msg, int64_t, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.UInt64Value */ |
||||
|
||||
UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_new(upb_arena *arena) { |
||||
return (google_protobuf_UInt64Value *)upb_msg_new(&google_protobuf_UInt64Value_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_UInt64Value *google_protobuf_UInt64Value_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_UInt64Value *ret = google_protobuf_UInt64Value_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_UInt64Value_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_UInt64Value_serialize(const google_protobuf_UInt64Value *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_UInt64Value_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE uint64_t google_protobuf_UInt64Value_value(const google_protobuf_UInt64Value *msg) { return UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_UInt64Value_set_value(google_protobuf_UInt64Value *msg, uint64_t value) { |
||||
UPB_FIELD_AT(msg, uint64_t, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.Int32Value */ |
||||
|
||||
UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_new(upb_arena *arena) { |
||||
return (google_protobuf_Int32Value *)upb_msg_new(&google_protobuf_Int32Value_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_Int32Value *google_protobuf_Int32Value_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_Int32Value *ret = google_protobuf_Int32Value_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_Int32Value_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_Int32Value_serialize(const google_protobuf_Int32Value *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_Int32Value_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE int32_t google_protobuf_Int32Value_value(const google_protobuf_Int32Value *msg) { return UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_Int32Value_set_value(google_protobuf_Int32Value *msg, int32_t value) { |
||||
UPB_FIELD_AT(msg, int32_t, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.UInt32Value */ |
||||
|
||||
UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_new(upb_arena *arena) { |
||||
return (google_protobuf_UInt32Value *)upb_msg_new(&google_protobuf_UInt32Value_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_UInt32Value *google_protobuf_UInt32Value_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_UInt32Value *ret = google_protobuf_UInt32Value_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_UInt32Value_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_UInt32Value_serialize(const google_protobuf_UInt32Value *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_UInt32Value_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE uint32_t google_protobuf_UInt32Value_value(const google_protobuf_UInt32Value *msg) { return UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_UInt32Value_set_value(google_protobuf_UInt32Value *msg, uint32_t value) { |
||||
UPB_FIELD_AT(msg, uint32_t, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.BoolValue */ |
||||
|
||||
UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_new(upb_arena *arena) { |
||||
return (google_protobuf_BoolValue *)upb_msg_new(&google_protobuf_BoolValue_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_BoolValue *google_protobuf_BoolValue_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_BoolValue *ret = google_protobuf_BoolValue_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_BoolValue_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_BoolValue_serialize(const google_protobuf_BoolValue *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_BoolValue_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE bool google_protobuf_BoolValue_value(const google_protobuf_BoolValue *msg) { return UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_BoolValue_set_value(google_protobuf_BoolValue *msg, bool value) { |
||||
UPB_FIELD_AT(msg, bool, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.StringValue */ |
||||
|
||||
UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_new(upb_arena *arena) { |
||||
return (google_protobuf_StringValue *)upb_msg_new(&google_protobuf_StringValue_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_StringValue *google_protobuf_StringValue_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_StringValue *ret = google_protobuf_StringValue_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_StringValue_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_StringValue_serialize(const google_protobuf_StringValue *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_StringValue_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE upb_strview google_protobuf_StringValue_value(const google_protobuf_StringValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_StringValue_set_value(google_protobuf_StringValue *msg, upb_strview value) { |
||||
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
/* google.protobuf.BytesValue */ |
||||
|
||||
UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_new(upb_arena *arena) { |
||||
return (google_protobuf_BytesValue *)upb_msg_new(&google_protobuf_BytesValue_msginit, arena); |
||||
} |
||||
UPB_INLINE google_protobuf_BytesValue *google_protobuf_BytesValue_parsenew(upb_strview buf, upb_arena *arena) { |
||||
google_protobuf_BytesValue *ret = google_protobuf_BytesValue_new(arena); |
||||
return (ret && upb_decode(buf, ret, &google_protobuf_BytesValue_msginit)) ? ret : NULL; |
||||
} |
||||
UPB_INLINE char *google_protobuf_BytesValue_serialize(const google_protobuf_BytesValue *msg, upb_arena *arena, size_t *len) { |
||||
return upb_encode(msg, &google_protobuf_BytesValue_msginit, arena, len); |
||||
} |
||||
|
||||
UPB_INLINE upb_strview google_protobuf_BytesValue_value(const google_protobuf_BytesValue *msg) { return UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)); } |
||||
|
||||
UPB_INLINE void google_protobuf_BytesValue_set_value(google_protobuf_BytesValue *msg, upb_strview value) { |
||||
UPB_FIELD_AT(msg, upb_strview, UPB_SIZE(0, 0)) = value; |
||||
} |
||||
|
||||
|
||||
#ifdef __cplusplus |
||||
} /* extern "C" */ |
||||
#endif |
||||
|
||||
#include "upb/port_undef.inc" |
||||
|
||||
#endif /* GOOGLE_PROTOBUF_WRAPPERS_PROTO_UPB_H_ */ |
@ -1,107 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/iomgr/port.h" |
||||
|
||||
#ifdef GRPC_POSIX_WAKEUP_FD |
||||
|
||||
#include "src/core/lib/iomgr/wakeup_fd_cv.h" |
||||
|
||||
#include <errno.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/sync.h> |
||||
#include <grpc/support/time.h> |
||||
|
||||
#include "src/core/lib/gpr/useful.h" |
||||
#include "src/core/lib/gprpp/thd.h" |
||||
|
||||
#define MAX_TABLE_RESIZE 256 |
||||
|
||||
extern grpc_cv_fd_table g_cvfds; |
||||
|
||||
static grpc_error* cv_fd_init(grpc_wakeup_fd* fd_info) { |
||||
unsigned int i, newsize; |
||||
int idx; |
||||
gpr_mu_lock(&g_cvfds.mu); |
||||
if (!g_cvfds.free_fds) { |
||||
newsize = GPR_MIN(g_cvfds.size * 2, g_cvfds.size + MAX_TABLE_RESIZE); |
||||
g_cvfds.cvfds = static_cast<grpc_fd_node*>( |
||||
gpr_realloc(g_cvfds.cvfds, sizeof(grpc_fd_node) * newsize)); |
||||
for (i = g_cvfds.size; i < newsize; i++) { |
||||
g_cvfds.cvfds[i].is_set = 0; |
||||
g_cvfds.cvfds[i].cvs = nullptr; |
||||
g_cvfds.cvfds[i].next_free = g_cvfds.free_fds; |
||||
g_cvfds.free_fds = &g_cvfds.cvfds[i]; |
||||
} |
||||
g_cvfds.size = newsize; |
||||
} |
||||
|
||||
idx = static_cast<int>(g_cvfds.free_fds - g_cvfds.cvfds); |
||||
g_cvfds.free_fds = g_cvfds.free_fds->next_free; |
||||
g_cvfds.cvfds[idx].cvs = nullptr; |
||||
g_cvfds.cvfds[idx].is_set = 0; |
||||
fd_info->read_fd = GRPC_IDX_TO_FD(idx); |
||||
fd_info->write_fd = -1; |
||||
gpr_mu_unlock(&g_cvfds.mu); |
||||
return GRPC_ERROR_NONE; |
||||
} |
||||
|
||||
static grpc_error* cv_fd_wakeup(grpc_wakeup_fd* fd_info) { |
||||
grpc_cv_node* cvn; |
||||
gpr_mu_lock(&g_cvfds.mu); |
||||
g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].is_set = 1; |
||||
cvn = g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].cvs; |
||||
while (cvn) { |
||||
gpr_cv_signal(cvn->cv); |
||||
cvn = cvn->next; |
||||
} |
||||
gpr_mu_unlock(&g_cvfds.mu); |
||||
return GRPC_ERROR_NONE; |
||||
} |
||||
|
||||
static grpc_error* cv_fd_consume(grpc_wakeup_fd* fd_info) { |
||||
gpr_mu_lock(&g_cvfds.mu); |
||||
g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].is_set = 0; |
||||
gpr_mu_unlock(&g_cvfds.mu); |
||||
return GRPC_ERROR_NONE; |
||||
} |
||||
|
||||
static void cv_fd_destroy(grpc_wakeup_fd* fd_info) { |
||||
if (fd_info->read_fd == 0) { |
||||
return; |
||||
} |
||||
gpr_mu_lock(&g_cvfds.mu); |
||||
// Assert that there are no active pollers
|
||||
GPR_ASSERT(!g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].cvs); |
||||
g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)].next_free = g_cvfds.free_fds; |
||||
g_cvfds.free_fds = &g_cvfds.cvfds[GRPC_FD_TO_IDX(fd_info->read_fd)]; |
||||
gpr_mu_unlock(&g_cvfds.mu); |
||||
} |
||||
|
||||
static int cv_check_availability(void) { return 1; } |
||||
|
||||
const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable = { |
||||
cv_fd_init, cv_fd_consume, cv_fd_wakeup, cv_fd_destroy, |
||||
cv_check_availability}; |
||||
|
||||
#endif /* GRPC_POSIX_WAKUP_FD */ |
@ -1,69 +0,0 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2016 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
/*
|
||||
* wakeup_fd_cv uses condition variables to implement wakeup fds. |
||||
* |
||||
* It is intended for use only in cases when eventfd() and pipe() are not |
||||
* available. It can only be used with the "poll" engine. |
||||
* |
||||
* Implementation: |
||||
* A global table of cv wakeup fds is mantained. A cv wakeup fd is a negative |
||||
* file descriptor. poll() is then run in a background thread with only the |
||||
* real socket fds while we wait on a condition variable trigged by either the |
||||
* poll() completion or a wakeup_fd() call. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H |
||||
#define GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/support/sync.h> |
||||
|
||||
#include "src/core/lib/iomgr/ev_posix.h" |
||||
|
||||
#define GRPC_FD_TO_IDX(fd) (-(fd)-1) |
||||
#define GRPC_IDX_TO_FD(idx) (-(idx)-1) |
||||
|
||||
typedef struct grpc_cv_node { |
||||
gpr_cv* cv; |
||||
struct grpc_cv_node* next; |
||||
struct grpc_cv_node* prev; |
||||
} grpc_cv_node; |
||||
|
||||
typedef struct grpc_fd_node { |
||||
int is_set; |
||||
grpc_cv_node* cvs; |
||||
struct grpc_fd_node* next_free; |
||||
} grpc_fd_node; |
||||
|
||||
typedef struct grpc_cv_fd_table { |
||||
gpr_mu mu; |
||||
gpr_refcount pollcount; |
||||
gpr_cv shutdown_cv; |
||||
grpc_fd_node* cvfds; |
||||
grpc_fd_node* free_fds; |
||||
unsigned int size; |
||||
grpc_poll_function_type poll; |
||||
} grpc_cv_fd_table; |
||||
|
||||
extern const grpc_wakeup_fd_vtable grpc_cv_wakeup_fd_vtable; |
||||
|
||||
#endif /* GRPC_CORE_LIB_IOMGR_WAKEUP_FD_CV_H */ |
@ -0,0 +1,129 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/security/credentials/tls/spiffe_credentials.h" |
||||
|
||||
#include <cstring> |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/lib/channel/channel_args.h" |
||||
#include "src/core/lib/security/security_connector/tls/spiffe_security_connector.h" |
||||
|
||||
#define GRPC_CREDENTIALS_TYPE_SPIFFE "Spiffe" |
||||
|
||||
namespace { |
||||
|
||||
bool CredentialOptionSanityCheck(const grpc_tls_credentials_options* options, |
||||
bool is_client) { |
||||
if (options == nullptr) { |
||||
gpr_log(GPR_ERROR, "SPIFFE TLS credentials options is nullptr."); |
||||
return false; |
||||
} |
||||
if (options->key_materials_config() == nullptr && |
||||
options->credential_reload_config() == nullptr) { |
||||
gpr_log( |
||||
GPR_ERROR, |
||||
"SPIFFE TLS credentials options must specify either key materials or " |
||||
"credential reload config."); |
||||
return false; |
||||
} |
||||
if (!is_client && options->server_authorization_check_config() != nullptr) { |
||||
gpr_log(GPR_INFO, |
||||
"Server's credentials options should not contain server " |
||||
"authorization check config."); |
||||
} |
||||
return true; |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
SpiffeCredentials::SpiffeCredentials( |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options) |
||||
: grpc_channel_credentials(GRPC_CREDENTIALS_TYPE_SPIFFE), |
||||
options_(std::move(options)) {} |
||||
|
||||
SpiffeCredentials::~SpiffeCredentials() {} |
||||
|
||||
grpc_core::RefCountedPtr<grpc_channel_security_connector> |
||||
SpiffeCredentials::create_security_connector( |
||||
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds, |
||||
const char* target_name, const grpc_channel_args* args, |
||||
grpc_channel_args** new_args) { |
||||
const char* overridden_target_name = nullptr; |
||||
tsi_ssl_session_cache* ssl_session_cache = nullptr; |
||||
for (size_t i = 0; args != nullptr && i < args->num_args; i++) { |
||||
grpc_arg* arg = &args->args[i]; |
||||
if (strcmp(arg->key, GRPC_SSL_TARGET_NAME_OVERRIDE_ARG) == 0 && |
||||
arg->type == GRPC_ARG_STRING) { |
||||
overridden_target_name = arg->value.string; |
||||
} |
||||
if (strcmp(arg->key, GRPC_SSL_SESSION_CACHE_ARG) == 0 && |
||||
arg->type == GRPC_ARG_POINTER) { |
||||
ssl_session_cache = |
||||
static_cast<tsi_ssl_session_cache*>(arg->value.pointer.p); |
||||
} |
||||
} |
||||
grpc_core::RefCountedPtr<grpc_channel_security_connector> sc = |
||||
SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector( |
||||
this->Ref(), std::move(call_creds), target_name, |
||||
overridden_target_name, ssl_session_cache); |
||||
if (sc == nullptr) { |
||||
return nullptr; |
||||
} |
||||
grpc_arg new_arg = grpc_channel_arg_string_create( |
||||
(char*)GRPC_ARG_HTTP2_SCHEME, (char*)"https"); |
||||
*new_args = grpc_channel_args_copy_and_add(args, &new_arg, 1); |
||||
return sc; |
||||
} |
||||
|
||||
SpiffeServerCredentials::SpiffeServerCredentials( |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options) |
||||
: grpc_server_credentials(GRPC_CREDENTIALS_TYPE_SPIFFE), |
||||
options_(std::move(options)) {} |
||||
|
||||
SpiffeServerCredentials::~SpiffeServerCredentials() {} |
||||
|
||||
grpc_core::RefCountedPtr<grpc_server_security_connector> |
||||
SpiffeServerCredentials::create_security_connector() { |
||||
return SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector( |
||||
this->Ref()); |
||||
} |
||||
|
||||
grpc_channel_credentials* grpc_tls_spiffe_credentials_create( |
||||
grpc_tls_credentials_options* options) { |
||||
if (!CredentialOptionSanityCheck(options, true /* is_client */)) { |
||||
return nullptr; |
||||
} |
||||
return grpc_core::New<SpiffeCredentials>( |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options>(options)); |
||||
} |
||||
|
||||
grpc_server_credentials* grpc_tls_spiffe_server_credentials_create( |
||||
grpc_tls_credentials_options* options) { |
||||
if (!CredentialOptionSanityCheck(options, false /* is_client */)) { |
||||
return nullptr; |
||||
} |
||||
return grpc_core::New<SpiffeServerCredentials>( |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options>(options)); |
||||
} |
@ -0,0 +1,62 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H |
||||
#define GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include <grpc/grpc_security.h> |
||||
|
||||
#include "src/core/lib/security/credentials/credentials.h" |
||||
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" |
||||
|
||||
class SpiffeCredentials final : public grpc_channel_credentials { |
||||
public: |
||||
explicit SpiffeCredentials( |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options); |
||||
~SpiffeCredentials() override; |
||||
|
||||
grpc_core::RefCountedPtr<grpc_channel_security_connector> |
||||
create_security_connector( |
||||
grpc_core::RefCountedPtr<grpc_call_credentials> call_creds, |
||||
const char* target_name, const grpc_channel_args* args, |
||||
grpc_channel_args** new_args) override; |
||||
|
||||
const grpc_tls_credentials_options& options() const { return *options_; } |
||||
|
||||
private: |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_; |
||||
}; |
||||
|
||||
class SpiffeServerCredentials final : public grpc_server_credentials { |
||||
public: |
||||
explicit SpiffeServerCredentials( |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options); |
||||
~SpiffeServerCredentials() override; |
||||
|
||||
grpc_core::RefCountedPtr<grpc_server_security_connector> |
||||
create_security_connector() override; |
||||
|
||||
const grpc_tls_credentials_options& options() const { return *options_; } |
||||
|
||||
private: |
||||
grpc_core::RefCountedPtr<grpc_tls_credentials_options> options_; |
||||
}; |
||||
|
||||
#endif /* GRPC_CORE_LIB_SECURITY_CREDENTIALS_TLS_SPIFFE_CREDENTIALS_H */ |
@ -0,0 +1,426 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/security/security_connector/tls/spiffe_security_connector.h" |
||||
|
||||
#include <stdbool.h> |
||||
#include <string.h> |
||||
|
||||
#include <grpc/grpc.h> |
||||
#include <grpc/support/alloc.h> |
||||
#include <grpc/support/log.h> |
||||
#include <grpc/support/string_util.h> |
||||
|
||||
#include "src/core/lib/gpr/host_port.h" |
||||
#include "src/core/lib/security/credentials/ssl/ssl_credentials.h" |
||||
#include "src/core/lib/security/credentials/tls/spiffe_credentials.h" |
||||
#include "src/core/lib/security/security_connector/ssl_utils.h" |
||||
#include "src/core/lib/security/transport/security_handshaker.h" |
||||
#include "src/core/lib/slice/slice_internal.h" |
||||
#include "src/core/lib/transport/transport.h" |
||||
#include "src/core/tsi/ssl_transport_security.h" |
||||
#include "src/core/tsi/transport_security.h" |
||||
|
||||
namespace { |
||||
|
||||
tsi_ssl_pem_key_cert_pair* ConvertToTsiPemKeyCertPair( |
||||
const grpc_tls_key_materials_config::PemKeyCertPairList& cert_pair_list) { |
||||
tsi_ssl_pem_key_cert_pair* tsi_pairs = nullptr; |
||||
size_t num_key_cert_pairs = cert_pair_list.size(); |
||||
if (num_key_cert_pairs > 0) { |
||||
GPR_ASSERT(cert_pair_list.data() != nullptr); |
||||
tsi_pairs = static_cast<tsi_ssl_pem_key_cert_pair*>( |
||||
gpr_zalloc(num_key_cert_pairs * sizeof(tsi_ssl_pem_key_cert_pair))); |
||||
} |
||||
for (size_t i = 0; i < num_key_cert_pairs; i++) { |
||||
GPR_ASSERT(cert_pair_list[i].private_key() != nullptr); |
||||
GPR_ASSERT(cert_pair_list[i].cert_chain() != nullptr); |
||||
tsi_pairs[i].cert_chain = gpr_strdup(cert_pair_list[i].cert_chain()); |
||||
tsi_pairs[i].private_key = gpr_strdup(cert_pair_list[i].private_key()); |
||||
} |
||||
return tsi_pairs; |
||||
} |
||||
|
||||
/** -- Util function to populate SPIFFE server/channel credentials. -- */ |
||||
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> |
||||
PopulateSpiffeCredentials(const grpc_tls_credentials_options& options) { |
||||
GPR_ASSERT(options.credential_reload_config() != nullptr || |
||||
options.key_materials_config() != nullptr); |
||||
grpc_core::RefCountedPtr<grpc_tls_key_materials_config> key_materials_config; |
||||
/* Use credential reload config to fetch credentials. */ |
||||
if (options.credential_reload_config() != nullptr) { |
||||
grpc_tls_credential_reload_arg* arg = |
||||
grpc_core::New<grpc_tls_credential_reload_arg>(); |
||||
key_materials_config = grpc_tls_key_materials_config_create()->Ref(); |
||||
arg->key_materials_config = key_materials_config.get(); |
||||
int result = options.credential_reload_config()->Schedule(arg); |
||||
if (result) { |
||||
/* Do not support async credential reload. */ |
||||
gpr_log(GPR_ERROR, "Async credential reload is unsupported now."); |
||||
} else { |
||||
grpc_ssl_certificate_config_reload_status status = arg->status; |
||||
if (status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_UNCHANGED) { |
||||
gpr_log(GPR_DEBUG, "Credential does not change after reload."); |
||||
} else if (status == GRPC_SSL_CERTIFICATE_CONFIG_RELOAD_FAIL) { |
||||
gpr_log(GPR_ERROR, "Credential reload failed with an error: %s", |
||||
arg->error_details); |
||||
} |
||||
} |
||||
gpr_free((void*)arg->error_details); |
||||
grpc_core::Delete(arg); |
||||
/* Use existing key materials config. */ |
||||
} else { |
||||
key_materials_config = options.key_materials_config()->Ref(); |
||||
} |
||||
return key_materials_config; |
||||
} |
||||
|
||||
} // namespace
|
||||
|
||||
SpiffeChannelSecurityConnector::SpiffeChannelSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds, |
||||
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds, |
||||
const char* target_name, const char* overridden_target_name) |
||||
: grpc_channel_security_connector(GRPC_SSL_URL_SCHEME, |
||||
std::move(channel_creds), |
||||
std::move(request_metadata_creds)), |
||||
overridden_target_name_(overridden_target_name == nullptr |
||||
? nullptr |
||||
: gpr_strdup(overridden_target_name)) { |
||||
check_arg_ = ServerAuthorizationCheckArgCreate(this); |
||||
char* port; |
||||
gpr_split_host_port(target_name, &target_name_, &port); |
||||
gpr_free(port); |
||||
} |
||||
|
||||
SpiffeChannelSecurityConnector::~SpiffeChannelSecurityConnector() { |
||||
if (target_name_ != nullptr) { |
||||
gpr_free(target_name_); |
||||
} |
||||
if (overridden_target_name_ != nullptr) { |
||||
gpr_free(overridden_target_name_); |
||||
} |
||||
if (client_handshaker_factory_ != nullptr) { |
||||
tsi_ssl_client_handshaker_factory_unref(client_handshaker_factory_); |
||||
} |
||||
ServerAuthorizationCheckArgDestroy(check_arg_); |
||||
} |
||||
|
||||
void SpiffeChannelSecurityConnector::add_handshakers( |
||||
grpc_pollset_set* interested_parties, |
||||
grpc_core::HandshakeManager* handshake_mgr) { |
||||
// Instantiate TSI handshaker.
|
||||
tsi_handshaker* tsi_hs = nullptr; |
||||
tsi_result result = tsi_ssl_client_handshaker_factory_create_handshaker( |
||||
client_handshaker_factory_, |
||||
overridden_target_name_ != nullptr ? overridden_target_name_ |
||||
: target_name_, |
||||
&tsi_hs); |
||||
if (result != TSI_OK) { |
||||
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", |
||||
tsi_result_to_string(result)); |
||||
return; |
||||
} |
||||
// Create handshakers.
|
||||
handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); |
||||
} |
||||
|
||||
void SpiffeChannelSecurityConnector::check_peer( |
||||
tsi_peer peer, grpc_endpoint* ep, |
||||
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context, |
||||
grpc_closure* on_peer_checked) { |
||||
const char* target_name = overridden_target_name_ != nullptr |
||||
? overridden_target_name_ |
||||
: target_name_; |
||||
grpc_error* error = grpc_ssl_check_alpn(&peer); |
||||
if (error != GRPC_ERROR_NONE) { |
||||
GRPC_CLOSURE_SCHED(on_peer_checked, error); |
||||
tsi_peer_destruct(&peer); |
||||
return; |
||||
} |
||||
*auth_context = grpc_ssl_peer_to_auth_context(&peer); |
||||
const SpiffeCredentials* creds = |
||||
static_cast<const SpiffeCredentials*>(channel_creds()); |
||||
const grpc_tls_server_authorization_check_config* config = |
||||
creds->options().server_authorization_check_config(); |
||||
/* If server authorization config is not null, use it to perform
|
||||
* server authorization check. */ |
||||
if (config != nullptr) { |
||||
const tsi_peer_property* p = |
||||
tsi_peer_get_property_by_name(&peer, TSI_X509_PEM_CERT_PROPERTY); |
||||
if (p == nullptr) { |
||||
error = GRPC_ERROR_CREATE_FROM_STATIC_STRING( |
||||
"Cannot check peer: missing pem cert property."); |
||||
} else { |
||||
char* peer_pem = static_cast<char*>(gpr_malloc(p->value.length + 1)); |
||||
memcpy(peer_pem, p->value.data, p->value.length); |
||||
peer_pem[p->value.length] = '\0'; |
||||
GPR_ASSERT(check_arg_ != nullptr); |
||||
check_arg_->peer_cert = check_arg_->peer_cert == nullptr |
||||
? gpr_strdup(peer_pem) |
||||
: check_arg_->peer_cert; |
||||
check_arg_->target_name = check_arg_->target_name == nullptr |
||||
? gpr_strdup(target_name) |
||||
: check_arg_->target_name; |
||||
on_peer_checked_ = on_peer_checked; |
||||
gpr_free(peer_pem); |
||||
int callback_status = config->Schedule(check_arg_); |
||||
/* Server authorization check is handled asynchronously. */ |
||||
if (callback_status) { |
||||
tsi_peer_destruct(&peer); |
||||
return; |
||||
} |
||||
/* Server authorization check is handled synchronously. */ |
||||
error = ProcessServerAuthorizationCheckResult(check_arg_); |
||||
} |
||||
} |
||||
GRPC_CLOSURE_SCHED(on_peer_checked, error); |
||||
tsi_peer_destruct(&peer); |
||||
} |
||||
|
||||
int SpiffeChannelSecurityConnector::cmp( |
||||
const grpc_security_connector* other_sc) const { |
||||
auto* other = |
||||
reinterpret_cast<const SpiffeChannelSecurityConnector*>(other_sc); |
||||
int c = channel_security_connector_cmp(other); |
||||
if (c != 0) { |
||||
return c; |
||||
} |
||||
return grpc_ssl_cmp_target_name(target_name_, other->target_name_, |
||||
overridden_target_name_, |
||||
other->overridden_target_name_); |
||||
} |
||||
|
||||
bool SpiffeChannelSecurityConnector::check_call_host( |
||||
const char* host, grpc_auth_context* auth_context, |
||||
grpc_closure* on_call_host_checked, grpc_error** error) { |
||||
return grpc_ssl_check_call_host(host, target_name_, overridden_target_name_, |
||||
auth_context, on_call_host_checked, error); |
||||
} |
||||
|
||||
void SpiffeChannelSecurityConnector::cancel_check_call_host( |
||||
grpc_closure* on_call_host_checked, grpc_error* error) { |
||||
GRPC_ERROR_UNREF(error); |
||||
} |
||||
|
||||
grpc_core::RefCountedPtr<grpc_channel_security_connector> |
||||
SpiffeChannelSecurityConnector::CreateSpiffeChannelSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds, |
||||
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds, |
||||
const char* target_name, const char* overridden_target_name, |
||||
tsi_ssl_session_cache* ssl_session_cache) { |
||||
if (channel_creds == nullptr) { |
||||
gpr_log(GPR_ERROR, |
||||
"channel_creds is nullptr in " |
||||
"SpiffeChannelSecurityConnectorCreate()"); |
||||
return nullptr; |
||||
} |
||||
if (target_name == nullptr) { |
||||
gpr_log(GPR_ERROR, |
||||
"target_name is nullptr in " |
||||
"SpiffeChannelSecurityConnectorCreate()"); |
||||
return nullptr; |
||||
} |
||||
grpc_core::RefCountedPtr<SpiffeChannelSecurityConnector> c = |
||||
grpc_core::MakeRefCounted<SpiffeChannelSecurityConnector>( |
||||
std::move(channel_creds), std::move(request_metadata_creds), |
||||
target_name, overridden_target_name); |
||||
if (c->InitializeHandshakerFactory(ssl_session_cache) != GRPC_SECURITY_OK) { |
||||
return nullptr; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
grpc_security_status |
||||
SpiffeChannelSecurityConnector::InitializeHandshakerFactory( |
||||
tsi_ssl_session_cache* ssl_session_cache) { |
||||
const SpiffeCredentials* creds = |
||||
static_cast<const SpiffeCredentials*>(channel_creds()); |
||||
auto key_materials_config = PopulateSpiffeCredentials(creds->options()); |
||||
if (key_materials_config->pem_key_cert_pair_list().empty()) { |
||||
key_materials_config->Unref(); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
tsi_ssl_pem_key_cert_pair* pem_key_cert_pair = ConvertToTsiPemKeyCertPair( |
||||
key_materials_config->pem_key_cert_pair_list()); |
||||
grpc_security_status status = grpc_ssl_tsi_client_handshaker_factory_init( |
||||
pem_key_cert_pair, key_materials_config->pem_root_certs(), |
||||
ssl_session_cache, &client_handshaker_factory_); |
||||
// Free memory.
|
||||
key_materials_config->Unref(); |
||||
grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pair, 1); |
||||
return status; |
||||
} |
||||
|
||||
void SpiffeChannelSecurityConnector::ServerAuthorizationCheckDone( |
||||
grpc_tls_server_authorization_check_arg* arg) { |
||||
GPR_ASSERT(arg != nullptr); |
||||
grpc_core::ExecCtx exec_ctx; |
||||
grpc_error* error = ProcessServerAuthorizationCheckResult(arg); |
||||
SpiffeChannelSecurityConnector* connector = |
||||
static_cast<SpiffeChannelSecurityConnector*>(arg->cb_user_data); |
||||
GRPC_CLOSURE_SCHED(connector->on_peer_checked_, error); |
||||
} |
||||
|
||||
grpc_error* |
||||
SpiffeChannelSecurityConnector::ProcessServerAuthorizationCheckResult( |
||||
grpc_tls_server_authorization_check_arg* arg) { |
||||
grpc_error* error = GRPC_ERROR_NONE; |
||||
char* msg = nullptr; |
||||
/* Server authorization check is cancelled by caller. */ |
||||
if (arg->status == GRPC_STATUS_CANCELLED) { |
||||
gpr_asprintf(&msg, |
||||
"Server authorization check is cancelled by the caller with " |
||||
"error: %s", |
||||
arg->error_details); |
||||
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); |
||||
} else if (arg->status == GRPC_STATUS_OK) { |
||||
/* Server authorization check completed successfully but returned check
|
||||
* failure. */ |
||||
if (!arg->success) { |
||||
gpr_asprintf(&msg, "Server authorization check failed with error: %s", |
||||
arg->error_details); |
||||
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); |
||||
} |
||||
/* Server authorization check did not complete correctly. */ |
||||
} else { |
||||
gpr_asprintf( |
||||
&msg, |
||||
"Server authorization check did not finish correctly with error: %s", |
||||
arg->error_details); |
||||
error = GRPC_ERROR_CREATE_FROM_COPIED_STRING(msg); |
||||
} |
||||
gpr_free(msg); |
||||
return error; |
||||
} |
||||
|
||||
grpc_tls_server_authorization_check_arg* |
||||
SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgCreate( |
||||
void* user_data) { |
||||
grpc_tls_server_authorization_check_arg* arg = |
||||
grpc_core::New<grpc_tls_server_authorization_check_arg>(); |
||||
arg->cb = ServerAuthorizationCheckDone; |
||||
arg->cb_user_data = user_data; |
||||
arg->status = GRPC_STATUS_OK; |
||||
return arg; |
||||
} |
||||
|
||||
void SpiffeChannelSecurityConnector::ServerAuthorizationCheckArgDestroy( |
||||
grpc_tls_server_authorization_check_arg* arg) { |
||||
if (arg == nullptr) { |
||||
return; |
||||
} |
||||
gpr_free((void*)arg->target_name); |
||||
gpr_free((void*)arg->peer_cert); |
||||
gpr_free((void*)arg->error_details); |
||||
grpc_core::Delete(arg); |
||||
} |
||||
|
||||
SpiffeServerSecurityConnector::SpiffeServerSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) |
||||
: grpc_server_security_connector(GRPC_SSL_URL_SCHEME, |
||||
std::move(server_creds)) {} |
||||
|
||||
SpiffeServerSecurityConnector::~SpiffeServerSecurityConnector() { |
||||
if (server_handshaker_factory_ != nullptr) { |
||||
tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); |
||||
} |
||||
} |
||||
|
||||
void SpiffeServerSecurityConnector::add_handshakers( |
||||
grpc_pollset_set* interested_parties, |
||||
grpc_core::HandshakeManager* handshake_mgr) { |
||||
/* Create a TLS SPIFFE TSI handshaker for server. */ |
||||
RefreshServerHandshakerFactory(); |
||||
tsi_handshaker* tsi_hs = nullptr; |
||||
tsi_result result = tsi_ssl_server_handshaker_factory_create_handshaker( |
||||
server_handshaker_factory_, &tsi_hs); |
||||
if (result != TSI_OK) { |
||||
gpr_log(GPR_ERROR, "Handshaker creation failed with error %s.", |
||||
tsi_result_to_string(result)); |
||||
return; |
||||
} |
||||
handshake_mgr->Add(grpc_core::SecurityHandshakerCreate(tsi_hs, this)); |
||||
} |
||||
|
||||
void SpiffeServerSecurityConnector::check_peer( |
||||
tsi_peer peer, grpc_endpoint* ep, |
||||
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context, |
||||
grpc_closure* on_peer_checked) { |
||||
grpc_error* error = grpc_ssl_check_alpn(&peer); |
||||
*auth_context = grpc_ssl_peer_to_auth_context(&peer); |
||||
tsi_peer_destruct(&peer); |
||||
GRPC_CLOSURE_SCHED(on_peer_checked, error); |
||||
} |
||||
|
||||
int SpiffeServerSecurityConnector::cmp( |
||||
const grpc_security_connector* other) const { |
||||
return server_security_connector_cmp( |
||||
static_cast<const grpc_server_security_connector*>(other)); |
||||
} |
||||
|
||||
grpc_core::RefCountedPtr<grpc_server_security_connector> |
||||
SpiffeServerSecurityConnector::CreateSpiffeServerSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds) { |
||||
if (server_creds == nullptr) { |
||||
gpr_log(GPR_ERROR, |
||||
"server_creds is nullptr in " |
||||
"SpiffeServerSecurityConnectorCreate()"); |
||||
return nullptr; |
||||
} |
||||
grpc_core::RefCountedPtr<SpiffeServerSecurityConnector> c = |
||||
grpc_core::MakeRefCounted<SpiffeServerSecurityConnector>( |
||||
std::move(server_creds)); |
||||
if (c->RefreshServerHandshakerFactory() != GRPC_SECURITY_OK) { |
||||
return nullptr; |
||||
} |
||||
return c; |
||||
} |
||||
|
||||
grpc_security_status |
||||
SpiffeServerSecurityConnector::RefreshServerHandshakerFactory() { |
||||
const SpiffeServerCredentials* creds = |
||||
static_cast<const SpiffeServerCredentials*>(server_creds()); |
||||
auto key_materials_config = PopulateSpiffeCredentials(creds->options()); |
||||
/* Credential reload does NOT take effect and we need to keep using
|
||||
* the existing handshaker factory. */ |
||||
if (key_materials_config->pem_key_cert_pair_list().empty()) { |
||||
key_materials_config->Unref(); |
||||
return GRPC_SECURITY_ERROR; |
||||
} |
||||
/* Credential reload takes effect and we need to free the existing
|
||||
* handshaker library. */ |
||||
if (server_handshaker_factory_) { |
||||
tsi_ssl_server_handshaker_factory_unref(server_handshaker_factory_); |
||||
} |
||||
tsi_ssl_pem_key_cert_pair* pem_key_cert_pairs = ConvertToTsiPemKeyCertPair( |
||||
key_materials_config->pem_key_cert_pair_list()); |
||||
size_t num_key_cert_pairs = |
||||
key_materials_config->pem_key_cert_pair_list().size(); |
||||
grpc_security_status status = grpc_ssl_tsi_server_handshaker_factory_init( |
||||
pem_key_cert_pairs, num_key_cert_pairs, |
||||
key_materials_config->pem_root_certs(), |
||||
creds->options().cert_request_type(), &server_handshaker_factory_); |
||||
// Free memory.
|
||||
key_materials_config->Unref(); |
||||
grpc_tsi_ssl_pem_key_cert_pairs_destroy(pem_key_cert_pairs, |
||||
num_key_cert_pairs); |
||||
return status; |
||||
} |
@ -0,0 +1,122 @@ |
||||
/*
|
||||
* |
||||
* Copyright 2018 gRPC authors. |
||||
* |
||||
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||
* you may not use this file except in compliance with the License. |
||||
* You may obtain a copy of the License at |
||||
* |
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
* |
||||
* Unless required by applicable law or agreed to in writing, software |
||||
* distributed under the License is distributed on an "AS IS" BASIS, |
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||
* See the License for the specific language governing permissions and |
||||
* limitations under the License. |
||||
* |
||||
*/ |
||||
|
||||
#ifndef GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H |
||||
#define GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H |
||||
|
||||
#include <grpc/support/port_platform.h> |
||||
|
||||
#include "src/core/lib/security/context/security_context.h" |
||||
#include "src/core/lib/security/credentials/tls/grpc_tls_credentials_options.h" |
||||
|
||||
#define GRPC_TLS_SPIFFE_TRANSPORT_SECURITY_TYPE "spiffe" |
||||
|
||||
// Spiffe channel security connector.
|
||||
class SpiffeChannelSecurityConnector final |
||||
: public grpc_channel_security_connector { |
||||
public: |
||||
// static factory method to create a SPIFFE channel security connector.
|
||||
static grpc_core::RefCountedPtr<grpc_channel_security_connector> |
||||
CreateSpiffeChannelSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds, |
||||
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds, |
||||
const char* target_name, const char* overridden_target_name, |
||||
tsi_ssl_session_cache* ssl_session_cache); |
||||
|
||||
SpiffeChannelSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_channel_credentials> channel_creds, |
||||
grpc_core::RefCountedPtr<grpc_call_credentials> request_metadata_creds, |
||||
const char* target_name, const char* overridden_target_name); |
||||
~SpiffeChannelSecurityConnector() override; |
||||
|
||||
void add_handshakers(grpc_pollset_set* interested_parties, |
||||
grpc_core::HandshakeManager* handshake_mgr) override; |
||||
|
||||
void check_peer(tsi_peer peer, grpc_endpoint* ep, |
||||
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context, |
||||
grpc_closure* on_peer_checked) override; |
||||
|
||||
int cmp(const grpc_security_connector* other_sc) const override; |
||||
|
||||
bool check_call_host(const char* host, grpc_auth_context* auth_context, |
||||
grpc_closure* on_call_host_checked, |
||||
grpc_error** error) override; |
||||
|
||||
void cancel_check_call_host(grpc_closure* on_call_host_checked, |
||||
grpc_error* error) override; |
||||
|
||||
private: |
||||
// Initialize SSL TSI client handshaker factory.
|
||||
grpc_security_status InitializeHandshakerFactory( |
||||
tsi_ssl_session_cache* ssl_session_cache); |
||||
|
||||
// gRPC-provided callback executed by application, which servers to bring the
|
||||
// control back to gRPC core.
|
||||
static void ServerAuthorizationCheckDone( |
||||
grpc_tls_server_authorization_check_arg* arg); |
||||
|
||||
// A util function to process server authorization check result.
|
||||
static grpc_error* ProcessServerAuthorizationCheckResult( |
||||
grpc_tls_server_authorization_check_arg* arg); |
||||
|
||||
// A util function to create a server authorization check arg instance.
|
||||
static grpc_tls_server_authorization_check_arg* |
||||
ServerAuthorizationCheckArgCreate(void* user_data); |
||||
|
||||
// A util function to destroy a server authorization check arg instance.
|
||||
static void ServerAuthorizationCheckArgDestroy( |
||||
grpc_tls_server_authorization_check_arg* arg); |
||||
|
||||
grpc_closure* on_peer_checked_; |
||||
char* target_name_; |
||||
char* overridden_target_name_; |
||||
tsi_ssl_client_handshaker_factory* client_handshaker_factory_ = nullptr; |
||||
grpc_tls_server_authorization_check_arg* check_arg_; |
||||
}; |
||||
|
||||
// Spiffe server security connector.
|
||||
class SpiffeServerSecurityConnector final |
||||
: public grpc_server_security_connector { |
||||
public: |
||||
// static factory method to create a SPIFFE server security connector.
|
||||
static grpc_core::RefCountedPtr<grpc_server_security_connector> |
||||
CreateSpiffeServerSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds); |
||||
|
||||
explicit SpiffeServerSecurityConnector( |
||||
grpc_core::RefCountedPtr<grpc_server_credentials> server_creds); |
||||
~SpiffeServerSecurityConnector() override; |
||||
|
||||
void add_handshakers(grpc_pollset_set* interested_parties, |
||||
grpc_core::HandshakeManager* handshake_mgr) override; |
||||
|
||||
void check_peer(tsi_peer peer, grpc_endpoint* ep, |
||||
grpc_core::RefCountedPtr<grpc_auth_context>* auth_context, |
||||
grpc_closure* on_peer_checked) override; |
||||
|
||||
int cmp(const grpc_security_connector* other) const override; |
||||
|
||||
private: |
||||
// A util function to refresh SSL TSI server handshaker factory with a valid
|
||||
// credential.
|
||||
grpc_security_status RefreshServerHandshakerFactory(); |
||||
tsi_ssl_server_handshaker_factory* server_handshaker_factory_ = nullptr; |
||||
}; |
||||
|
||||
#endif /* GRPC_CORE_LIB_SECURITY_SECURITY_CONNECTOR_TLS_SPIFFE_SECURITY_CONNECTOR_H \ |
||||
*/ |
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in new issue