Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in / Register
Toggle navigation
P
protobuf
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Packages
Packages
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
submodule
protobuf
Commits
a7252bf4
Unverified
Commit
a7252bf4
authored
6 years ago
by
Feng Xiao
Committed by
GitHub
6 years ago
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #4698 from ThomasColthurst/proto_c_api
Introduce Proto C API; based on cl/198113115 by amauryfa
parents
17ab85de
7c651424
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
148 additions
and
1 deletion
+148
-1
BUILD
BUILD
+10
-0
Makefile.am
Makefile.am
+1
-0
proto_api.h
python/google/protobuf/proto_api.h
+92
-0
message.cc
python/google/protobuf/pyext/message.cc
+25
-1
message.h
python/google/protobuf/pyext/message.h
+3
-0
message_module.cc
python/google/protobuf/pyext/message_module.cc
+17
-0
No files found.
BUILD
View file @
a7252bf4
...
...
@@ -671,6 +671,7 @@ cc_binary(
linkstatic = 1,
deps = [
":protobuf",
":proto_api",
] + select({
"//conditions:default": [],
":use_fast_cpp_protos": ["//external:python_headers"],
...
...
@@ -813,6 +814,15 @@ internal_protobuf_py_tests(
deps = [":python_tests"],
)
cc_library(
name = "proto_api",
hdrs = ["python/google/protobuf/proto_api.h"],
deps = [
":protobuf_python",
"//external:python_headers",
],
)
proto_lang_toolchain(
name = "cc_toolchain",
command_line = "--cpp_out=$(OUT)",
...
...
This diff is collapsed.
Click to expand it.
Makefile.am
View file @
a7252bf4
...
...
@@ -804,6 +804,7 @@ python_EXTRA_DIST= \
python/google/protobuf/message.py
\
python/google/protobuf/message_factory.py
\
python/google/protobuf/python_protobuf.h
\
python/google/protobuf/proto_api.h
\
python/google/protobuf/proto_builder.py
\
python/google/protobuf/pyext/README
\
python/google/protobuf/pyext/__init__.py
\
...
...
This diff is collapsed.
Click to expand it.
python/google/protobuf/proto_api.h
0 → 100644
View file @
a7252bf4
// Protocol Buffers - Google's data interchange format
// Copyright 2008 Google Inc. All rights reserved.
// https://developers.google.com/protocol-buffers/
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are
// met:
//
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above
// copyright notice, this list of conditions and the following disclaimer
// in the documentation and/or other materials provided with the
// distribution.
// * Neither the name of Google Inc. nor the names of its
// contributors may be used to endorse or promote products derived from
// this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
// This file can be included by other C++ libraries, typically extension modules
// which want to interact with the Python Messages coming from the "cpp"
// implementation of protocol buffers.
//
// Usage:
// Declare a (probably static) variable to hold the API:
// const PyProto_API* py_proto_api;
// In some initialization function, write:
// py_proto_api = static_cast<const PyProto_API*>(PyCapsule_Import(
// PyProtoAPICapsuleName(), 0));
// if (!py_proto_api) { ...handle ImportError... }
// Then use the methods of the returned class:
// py_proto_api->GetMessagePointer(...);
#ifndef PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
#define PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
#include <Python.h>
namespace
google
{
namespace
protobuf
{
class
Message
;
namespace
python
{
// Note on the implementation:
// This API is designed after
// https://docs.python.org/3/extending/extending.html#providing-a-c-api-for-an-extension-module
// The class below contains no mutable state, and all methods are "const";
// we use a C++ class instead of a C struct with functions pointers just because
// the code looks more readable.
struct
PyProto_API
{
// The API object is created at initialization time and never freed.
// This destructor is never called.
virtual
~
PyProto_API
()
{}
// Operations on Messages.
// If the passed object is a Python Message, returns its internal pointer.
// Otherwise, returns NULL with an exception set.
virtual
const
Message
*
GetMessagePointer
(
PyObject
*
msg
)
const
=
0
;
// If the passed object is a Python Message, returns a mutable pointer.
// Otherwise, returns NULL with an exception set.
// This function will succeed only if there are no other Python objects
// pointing to the message, like submessages or repeated containers.
// With the current implementation, only empty messages are in this case.
virtual
Message
*
GetMutableMessagePointer
(
PyObject
*
msg
)
const
=
0
;
};
inline
const
char
*
PyProtoAPICapsuleName
()
{
static
const
char
kCapsuleName
[]
=
"protobuf.python.google.protobuf.cpp._message.proto_API"
;
return
kCapsuleName
;
}
}
// namespace python
}
// namespace protobuf
}
// namespace google
#endif // PYTHON_GOOGLE_PROTOBUF_PROTO_API_H__
This diff is collapsed.
Click to expand it.
python/google/protobuf/pyext/message.cc
View file @
a7252bf4
...
...
@@ -2866,17 +2866,38 @@ const Message* (*GetCProtoInsidePyProtoPtr)(PyObject* msg);
Message
*
(
*
MutableCProtoInsidePyProtoPtr
)(
PyObject
*
msg
);
static
const
Message
*
GetCProtoInsidePyProtoImpl
(
PyObject
*
msg
)
{
const
Message
*
message
=
PyMessage_GetMessagePointer
(
msg
);
if
(
message
==
NULL
)
{
PyErr_Clear
();
return
NULL
;
}
return
message
;
}
static
Message
*
MutableCProtoInsidePyProtoImpl
(
PyObject
*
msg
)
{
Message
*
message
=
PyMessage_GetMutableMessagePointer
(
msg
);
if
(
message
==
NULL
)
{
PyErr_Clear
();
return
NULL
;
}
return
message
;
}
const
Message
*
PyMessage_GetMessagePointer
(
PyObject
*
msg
)
{
if
(
!
PyObject_TypeCheck
(
msg
,
&
CMessage_Type
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Not a Message instance"
);
return
NULL
;
}
CMessage
*
cmsg
=
reinterpret_cast
<
CMessage
*>
(
msg
);
return
cmsg
->
message
;
}
static
Message
*
MutableCProtoInsidePyProtoImpl
(
PyObject
*
msg
)
{
Message
*
PyMessage_GetMutableMessagePointer
(
PyObject
*
msg
)
{
if
(
!
PyObject_TypeCheck
(
msg
,
&
CMessage_Type
))
{
PyErr_SetString
(
PyExc_TypeError
,
"Not a Message instance"
);
return
NULL
;
}
CMessage
*
cmsg
=
reinterpret_cast
<
CMessage
*>
(
msg
);
if
((
cmsg
->
composite_fields
&&
PyDict_Size
(
cmsg
->
composite_fields
)
!=
0
)
||
(
cmsg
->
extensions
!=
NULL
&&
...
...
@@ -2885,6 +2906,9 @@ static Message* MutableCProtoInsidePyProtoImpl(PyObject* msg) {
// the underlying C++ message back to the CMessage (e.g. removed repeated
// composite containers). We only allow direct mutation of the underlying
// C++ message if there is no child data in the CMessage.
PyErr_SetString
(
PyExc_ValueError
,
"Cannot reliably get a mutable pointer "
"to a message with extra references"
);
return
NULL
;
}
cmessage
::
AssureWritable
(
cmsg
);
...
...
This diff is collapsed.
Click to expand it.
python/google/protobuf/pyext/message.h
View file @
a7252bf4
...
...
@@ -341,6 +341,9 @@ bool CheckFieldBelongsToMessage(const FieldDescriptor* field_descriptor,
extern
PyObject
*
PickleError_class
;
const
Message
*
PyMessage_GetMessagePointer
(
PyObject
*
msg
);
Message
*
PyMessage_GetMutableMessagePointer
(
PyObject
*
msg
);
bool
InitProto2MessageModule
(
PyObject
*
m
);
#if LANG_CXX11
...
...
This diff is collapsed.
Click to expand it.
python/google/protobuf/pyext/message_module.cc
View file @
a7252bf4
...
...
@@ -31,9 +31,26 @@
#include <Python.h>
#include <google/protobuf/pyext/message.h>
#include <google/protobuf/proto_api.h>
#include <google/protobuf/message_lite.h>
namespace
{
// C++ API. Clients get at this via proto_api.h
struct
ApiImplementation
:
google
::
protobuf
::
python
::
PyProto_API
{
const
google
::
protobuf
::
Message
*
GetMessagePointer
(
PyObject
*
msg
)
const
override
{
return
google
::
protobuf
::
python
::
PyMessage_GetMessagePointer
(
msg
);
}
google
::
protobuf
::
Message
*
GetMutableMessagePointer
(
PyObject
*
msg
)
const
override
{
return
google
::
protobuf
::
python
::
PyMessage_GetMutableMessagePointer
(
msg
);
}
};
}
// namespace
static
PyObject
*
GetPythonProto3PreserveUnknownsDefault
(
PyObject
*
/*m*/
,
PyObject
*
/*args*/
)
{
if
(
google
::
protobuf
::
internal
::
GetProto3PreserveUnknownsDefault
())
{
...
...
This diff is collapsed.
Click to expand it.
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment