1
#include "source/common/formatter/substitution_format_string.h"
2

            
3
namespace Envoy {
4
namespace Formatter {
5

            
6
absl::StatusOr<std::vector<CommandParserPtr>> SubstitutionFormatStringUtils::parseFormatters(
7
    const FormattersConfig& formatters, Server::Configuration::GenericFactoryContext& context,
8
3104
    std::vector<CommandParserPtr>&& commands_parsers) {
9
3104
  std::vector<CommandParserPtr> commands = std::move(commands_parsers);
10
3104
  for (const auto& formatter : formatters) {
11
25
    auto* factory = Envoy::Config::Utility::getFactory<CommandParserFactory>(formatter);
12
25
    if (!factory) {
13
3
      return absl::InvalidArgumentError(absl::StrCat("Formatter not found: ", formatter.name()));
14
3
    }
15
22
    auto typed_config = Envoy::Config::Utility::translateAnyToFactoryConfig(
16
22
        formatter.typed_config(), context.messageValidationVisitor(), *factory);
17
22
    auto parser = factory->createCommandParserFromProto(*typed_config, context);
18
22
    if (!parser) {
19
2
      return absl::InvalidArgumentError(
20
2
          absl::StrCat("Failed to create command parser: ", formatter.name()));
21
2
    }
22
20
    commands.push_back(std::move(parser));
23
20
  }
24

            
25
3099
  return commands;
26
3104
}
27

            
28
absl::StatusOr<FormatterPtr> SubstitutionFormatStringUtils::fromProtoConfig(
29
    const envoy::config::core::v3::SubstitutionFormatString& config,
30
    Server::Configuration::GenericFactoryContext& context,
31
3070
    std::vector<CommandParserPtr>&& command_parsers) {
32
  // Instantiate formatter extensions.
33
3070
  auto commands = parseFormatters(config.formatters(), context, std::move(command_parsers));
34
3070
  RETURN_IF_NOT_OK_REF(commands.status());
35

            
36
3068
  switch (config.format_case()) {
37
1
  case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kTextFormat:
38
1
    return FormatterImpl::create(config.text_format(), config.omit_empty_values(), *commands);
39
124
  case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kJsonFormat:
40
124
    return createJsonFormatter(config.json_format(), config.omit_empty_values(), *commands);
41
2943
  case envoy::config::core::v3::SubstitutionFormatString::FormatCase::kTextFormatSource: {
42
2943
    auto data_source_or_error = Config::DataSource::read(config.text_format_source(), true,
43
2943
                                                         context.serverFactoryContext().api());
44
2943
    RETURN_IF_NOT_OK(data_source_or_error.status());
45
2943
    return FormatterImpl::create(*data_source_or_error, config.omit_empty_values(), *commands);
46
2943
  }
47
  case envoy::config::core::v3::SubstitutionFormatString::FormatCase::FORMAT_NOT_SET:
48
    PANIC_DUE_TO_PROTO_UNSET;
49
3068
  }
50

            
51
  return nullptr;
52
3068
}
53

            
54
FormatterPtr
55
SubstitutionFormatStringUtils::createJsonFormatter(const Protobuf::Struct& struct_format,
56
                                                   bool omit_empty_values,
57
133
                                                   const std::vector<CommandParserPtr>& commands) {
58
133
  return std::make_unique<JsonFormatterImpl>(struct_format, omit_empty_values, commands);
59
133
}
60

            
61
} // namespace Formatter
62
} // namespace Envoy