// 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. #ifndef GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__ #define GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__ #include #include #include namespace google { namespace protobuf { // A default/no-op implementation of message hooks. // // See go/statically-dispatched-message-hooks for details. template struct NoOpAccessListener { // Number of fields are provided at compile time for the trackers to be able // to have stack allocated bitmaps for the fields. This is useful for // performance critical trackers. This is also to avoid cyclic dependencies // if the number of fields is needed. static constexpr int kFields = Proto::_kInternalFieldNumber; // Default constructor is called during the static global initialization of // the program. // We provide a pointer to extract the name of the proto not to get cyclic // dependencies on GetDescriptor() and OnGetMetadata() calls. If you want // to differentiate the protos during the runtime before the start of the // program, use this functor to get its name. We either way need it for // LITE_RUNTIME protos as they don't have descriptors at all. explicit NoOpAccessListener(StringPiece (*name_extractor)()) {} // called repeatedly during serialization/deserialization/ByteSize of // Reflection as: // AccessListener::OnSerialize(this); static void OnSerialize(const MessageLite* msg) {} static void OnDeserialize(const MessageLite* msg) {} static void OnByteSize(const MessageLite* msg) {} static void OnMergeFrom(const MessageLite* to, const MessageLite* from) {} // NOTE: This function can be called pre-main. Make sure it does not make // the state of the listener invalid. static void OnGetMetadata() {} // called from accessors as: // AccessListener::On$operation(this, &field_storage_); // If you need to override this with type, in your hook implementation // introduce // template // static void On$operation(const MessageLite* msg, // const T* field) {} // And overloads for std::nullptr_t for incomplete types such as Messages, // Maps. Extract them using reflection if you need. Consequently, second // argument can be null pointer. // For an example, see proto_hooks/testing/memory_test_field_listener.h // And argument template deduction will deduce the type itself without // changing the generated code. // add_(f) template static void OnAdd(const MessageLite* msg, const void* field) {} // add_() template static void OnAddMutable(const MessageLite* msg, const void* field) {} // () and (i) template static void OnGet(const MessageLite* msg, const void* field) {} // clear_() template static void OnClear(const MessageLite* msg, const void* field) {} // has_() template static void OnHas(const MessageLite* msg, const void* field) {} // () template static void OnList(const MessageLite* msg, const void* field) {} // mutable_() template static void OnMutable(const MessageLite* msg, const void* field) {} // mutable_() template static void OnMutableList(const MessageLite* msg, const void* field) {} // release_() template static void OnRelease(const MessageLite* msg, const void* field) {} // set_() and set_(i) template static void OnSet(const MessageLite* msg, const void* field) {} // _size() template static void OnSize(const MessageLite* msg, const void* field) {} static void OnHasExtension(const MessageLite* msg, int extension_tag, const void* field) {} // TODO(b/190614678): Support clear in the proto compiler. static void OnClearExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnExtensionSize(const MessageLite* msg, int extension_tag, const void* field) {} static void OnGetExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnMutableExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnSetExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnReleaseExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnAddExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnAddMutableExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnListExtension(const MessageLite* msg, int extension_tag, const void* field) {} static void OnMutableListExtension(const MessageLite* msg, int extension_tag, const void* field) {} }; } // namespace protobuf } // namespace google #ifndef REPLACE_PROTO_LISTENER_IMPL namespace google { namespace protobuf { template using AccessListener = NoOpAccessListener; } // namespace protobuf } // namespace google #else // You can put your implementations of hooks/listeners here. // All hooks are subject to approval by protobuf-team@. #endif // !REPLACE_PROTO_LISTENER_IMPL #endif // GOOGLE_PROTOBUF_FIELD_ACCESS_LISTENER_H__