1
#include "source/common/protobuf/message_validator_impl.h"
2

            
3
#include "envoy/common/exception.h"
4

            
5
#include "source/common/common/assert.h"
6
#include "source/common/common/hash.h"
7
#include "source/common/common/macros.h"
8

            
9
#include "absl/strings/str_cat.h"
10

            
11
namespace Envoy {
12
namespace ProtobufMessage {
13

            
14
namespace {
15
const char deprecation_error[] = " If continued use of this field is absolutely necessary, "
16
                                 "see " ENVOY_DOC_URL_RUNTIME_OVERRIDE_DEPRECATED " for "
17
                                 "how to apply a temporary and highly discouraged override.";
18

            
19
absl::Status onDeprecatedFieldCommon(absl::string_view description, bool soft_deprecation,
20
284
                                     bool skip_deprecated_logs) {
21
284
  if (soft_deprecation) {
22
273
    if (!skip_deprecated_logs) {
23
271
      ENVOY_LOG_MISC(warn, "Deprecated field: {}", absl::StrCat(description, deprecation_error));
24
271
    }
25
273
  } else {
26
11
    return absl::InvalidArgumentError(absl::StrCat(description, deprecation_error));
27
11
  }
28
273
  return absl::OkStatus();
29
284
}
30
} // namespace
31

            
32
32016
void WipCounterBase::setWipCounter(Stats::Counter& wip_counter) {
33
32016
  ASSERT(wip_counter_ == nullptr);
34
32016
  wip_counter_ = &wip_counter;
35
32016
  wip_counter.add(prestats_wip_count_);
36
32016
}
37

            
38
6718
void WipCounterBase::onWorkInProgressCommon(absl::string_view description) {
39
6718
  ENVOY_LOG_MISC(warn, "{}", description);
40
6718
  if (wip_counter_ != nullptr) {
41
5316
    wip_counter_->inc();
42
6716
  } else {
43
1402
    prestats_wip_count_++;
44
1402
  }
45
6718
}
46

            
47
void WarningValidationVisitorImpl::setCounters(Stats::Counter& unknown_counter,
48
21344
                                               Stats::Counter& wip_counter) {
49
21344
  setWipCounter(wip_counter);
50
21344
  ASSERT(unknown_counter_ == nullptr);
51
21344
  unknown_counter_ = &unknown_counter;
52
21344
  unknown_counter.add(prestats_unknown_count_);
53
21344
}
54

            
55
17
absl::Status WarningValidationVisitorImpl::onUnknownField(absl::string_view description) {
56
17
  const uint64_t hash = HashUtil::xxHash64(description);
57
17
  auto it = descriptions_.insert(hash);
58
  // If we've seen this before, skip.
59
17
  if (!it.second) {
60
1
    return absl::OkStatus();
61
1
  }
62

            
63
  // It's a new field, log and bump stat.
64
16
  ENVOY_LOG(warn, "Unknown field: {}", description);
65
16
  if (unknown_counter_ == nullptr) {
66
6
    ++prestats_unknown_count_;
67
11
  } else {
68
10
    unknown_counter_->inc();
69
10
  }
70
16
  return absl::OkStatus();
71
17
}
72

            
73
absl::Status WarningValidationVisitorImpl::onDeprecatedField(absl::string_view description,
74
2
                                                             bool soft_deprecation) {
75
2
  return onDeprecatedFieldCommon(description, soft_deprecation, isSkipDeprecatedLogs());
76
2
}
77

            
78
2
void WarningValidationVisitorImpl::onWorkInProgress(absl::string_view description) {
79
2
  onWorkInProgressCommon(description);
80
2
}
81

            
82
60
absl::Status StrictValidationVisitorImpl::onUnknownField(absl::string_view description) {
83
60
  return absl::InvalidArgumentError(
84
60
      absl::StrCat("Protobuf message (", description, ") has unknown fields"));
85
60
}
86

            
87
absl::Status StrictValidationVisitorImpl::onDeprecatedField(absl::string_view description,
88
282
                                                            bool soft_deprecation) {
89
282
  return onDeprecatedFieldCommon(description, soft_deprecation, isSkipDeprecatedLogs());
90
282
}
91

            
92
6716
void StrictValidationVisitorImpl::onWorkInProgress(absl::string_view description) {
93
6716
  onWorkInProgressCommon(description);
94
6716
}
95

            
96
1032
ValidationVisitor& getNullValidationVisitor() {
97
1032
  MUTABLE_CONSTRUCT_ON_FIRST_USE(NullValidationVisitorImpl);
98
1032
}
99

            
100
175547
ValidationVisitor& getStrictValidationVisitor() {
101
175547
  MUTABLE_CONSTRUCT_ON_FIRST_USE(StrictValidationVisitorImpl);
102
175547
}
103

            
104
} // namespace ProtobufMessage
105
} // namespace Envoy