Module: SchemaRegistry::Output::JsonSchema

Defined in:
lib/schema_registry_client/output/json_schema.rb

Class Method Summary collapse

Class Method Details

.fetch(message_name) ⇒ Object



7
8
9
10
# File 'lib/schema_registry_client/output/json_schema.rb', line 7

def fetch(message_name)
  name = message_name.start_with?(".") ? message_name[1..] : message_name
  Google::Protobuf::DescriptorPool.generated_pool.lookup(name)
end

.field_object(field, ignore_repeated: false) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/schema_registry_client/output/json_schema.rb', line 40

def field_object(field, ignore_repeated: false)
  klass = fetch(field.type_name)&.to_proto
  if field.label == :LABEL_REPEATED && !ignore_repeated
    if klass&.options.respond_to?(:map_entry) && klass.options.map_entry
      return {
        type: "object",
        additionalProperties: field_object(klass.field[1])
      }
    end
    return {
      type: "array",
      items: field_object(field, ignore_repeated: true)
    }
  end
  field_type(field, klass)
end

.field_type(field, klass) ⇒ Object



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/schema_registry_client/output/json_schema.rb', line 57

def field_type(field, klass)
  case field.type
  when :TYPE_INT32, :TYPE_UINT32, :TYPE_SINT32, :TYPE_FIXED32, :TYPE_SFIXED32
    {type: "integer"}
  when :TYPE_FLOAT, :TYPE_DOUBLE
    {type: "number"}
  when :TYPE_INT64, :TYPE_UINT64, :TYPE_SINT64, :TYPE_FIXED64, :TYPE_SFIXED64, :TYPE_STRING, :TYPE_BYTES
    {type: "string"}
  when :TYPE_BOOL
    {type: "boolean"}
  else
    if klass.is_a?(Google::Protobuf::EnumDescriptorProto)
      {enum: klass.to_h[:value].map { |h| h[:name] }}
    else
      {type: "object"}
    end
  end
end

.output(descriptor, path: nil) ⇒ Object



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/schema_registry_client/output/json_schema.rb', line 12

def output(descriptor, path: nil)
  properties = {}
  result = {
    "$schema": "https://json-schema.org/draft/2020-12/schema",
    type: "object",
    properties: properties
  }
  if path
    # follow path down
    parts = path.split(".")
    field_name = parts.last
    parts[...-1].each do |part|
      field = descriptor.field.find { |f| f.name == part }
      raise "Field #{part} not found in #{descriptor.name}" unless field

      descriptor = fetch(field.type_name)&.to_proto
    end
    result[:required] = [field_name]
    properties[field_name] = field_object(descriptor.field.find { |f| f.name == field_name.to_s })
  else
    result[:required] = descriptor.field.reject(&:proto3_optional).map(&:name)
    descriptor.field.each do |f|
      properties[f.name] = field_object(f)
    end
  end
  JSON.pretty_generate(result)
end