1 // Protocol Buffers - Google's data interchange format 2 // Copyright 2008 Google Inc. All rights reserved. 3 // 4 // Use of this source code is governed by a BSD-style 5 // license that can be found in the LICENSE file or at 6 // https://developers.google.com/open-source/licenses/bsd 7 8 #ifndef GOOGLE_PROTOBUF_JSON_INTERNAL_MESSAGE_PATH_H__ 9 #define GOOGLE_PROTOBUF_JSON_INTERNAL_MESSAGE_PATH_H__ 10 11 #include <string> 12 #include <vector> 13 14 #include "absl/cleanup/cleanup.h" 15 #include "absl/strings/string_view.h" 16 #include "google/protobuf/descriptor.h" 17 18 namespace google { 19 namespace protobuf { 20 namespace json_internal { 21 // A path in a Protobuf message, annotated specifically for producing nice 22 // errors. 23 class MessagePath { 24 public: MessagePath(absl::string_view message_root)25 explicit MessagePath(absl::string_view message_root) 26 : components_( 27 {Component{FieldDescriptor::TYPE_MESSAGE, message_root, "", -1}}) {} 28 29 // Pushes a new field name, along with an optional type name if it is 30 // a message or enum. 31 // 32 // Returns an RAII object that will pop the field component on scope exit. 33 auto Push(absl::string_view field_name, FieldDescriptor::Type type, 34 absl::string_view type_name = "") { 35 // -1 makes it so the first call to NextRepeated makes the index 0. 36 components_.push_back(Component{type, type_name, field_name, -1}); 37 return absl::MakeCleanup([this] { components_.pop_back(); }); 38 } 39 40 // Increments the index of this field, indicating it is a repeated field. 41 // 42 // The first time this is called, the field will be marked as repeated and 43 // the index will become 0. NextRepeated()44 void NextRepeated() { ++components_.back().repeated_index; } 45 46 // Appends a description of the current state of the path to `out`. 47 void Describe(std::string& out) const; 48 49 private: 50 struct Component { 51 FieldDescriptor::Type type; 52 absl::string_view type_name, field_name; 53 int32_t repeated_index; 54 }; 55 std::vector<Component> components_; 56 }; 57 } // namespace json_internal 58 } // namespace protobuf 59 } // namespace google 60 61 #endif // GOOGLE_PROTOBUF_JSON_INTERNAL_MESSAGE_PATH_H__ 62